diff --git a/kura-apps-distrib/kura-examples/pom.xml b/kura-apps-distrib/kura-examples/pom.xml index 9da98a42..b5e6f43c 100644 --- a/kura-apps-distrib/kura-examples/pom.xml +++ b/kura-apps-distrib/kura-examples/pom.xml @@ -42,7 +42,7 @@ modbus publishers security - sensehat + wire-components diff --git a/kura-apps-target-definition/kura-apps.target b/kura-apps-target-definition/kura-apps.target index 4ca1dfaa..679b109c 100644 --- a/kura-apps-target-definition/kura-apps.target +++ b/kura-apps-target-definition/kura-apps.target @@ -13,7 +13,8 @@ Contributors: Eurotech ---> +--> + diff --git a/kura-examples/bundles/gpio/org.eclipse.kura.example.gpio/META-INF/MANIFEST.MF b/kura-examples/bundles/gpio/org.eclipse.kura.example.gpio/META-INF/MANIFEST.MF index a6a1b950..1c650714 100644 --- a/kura-examples/bundles/gpio/org.eclipse.kura.example.gpio/META-INF/MANIFEST.MF +++ b/kura-examples/bundles/gpio/org.eclipse.kura.example.gpio/META-INF/MANIFEST.MF @@ -8,7 +8,7 @@ Require-Capability: osgi.ee;filter:="(&(osgi.ee=JavaSE)(version=17))" Service-Component: OSGI-INF/*.xml Import-Package: org.eclipse.kura;version="[1.0,2.0)", org.eclipse.kura.configuration;version="[1.0,2.0)", - org.eclipse.kura.gpio;version="1.0.0", + org.eclipse.kura.gpio;version="[1.2,2.0)", org.osgi.framework;version="1.8.0", org.osgi.service.component;version="1.2.0", org.osgi.util.tracker;version="1.5.1", diff --git a/kura-examples/bundles/gpio/org.eclipse.kura.example.gpio/src/main/java/org/eclipse/kura/example/gpio/GpioComponent.java b/kura-examples/bundles/gpio/org.eclipse.kura.example.gpio/src/main/java/org/eclipse/kura/example/gpio/GpioComponent.java index c717fcae..30eefed9 100644 --- a/kura-examples/bundles/gpio/org.eclipse.kura.example.gpio/src/main/java/org/eclipse/kura/example/gpio/GpioComponent.java +++ b/kura-examples/bundles/gpio/org.eclipse.kura.example.gpio/src/main/java/org/eclipse/kura/example/gpio/GpioComponent.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2011, 2025 Eurotech and/or its affiliates and others + * Copyright (c) 2011, 2026 Eurotech and/or its affiliates and others * * This program and the accompanying materials are made * available under the terms of the Eclipse Public License 2.0 @@ -17,9 +17,9 @@ import java.io.IOException; import java.util.ArrayList; +import java.util.HashMap; import java.util.List; import java.util.Map; -import java.util.Map.Entry; import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.ScheduledFuture; @@ -29,6 +29,8 @@ import org.eclipse.kura.configuration.ConfigurableComponent; import org.eclipse.kura.gpio.GPIOService; import org.eclipse.kura.gpio.KuraClosedDeviceException; +import org.eclipse.kura.gpio.KuraGPIODescription; +import org.eclipse.kura.gpio.KuraGPIODeviceException; import org.eclipse.kura.gpio.KuraGPIODirection; import org.eclipse.kura.gpio.KuraGPIOMode; import org.eclipse.kura.gpio.KuraGPIOPin; @@ -62,8 +64,10 @@ public class GpioComponent implements ConfigurableComponent { /** - * Inner class defined to track the CloudServices as they get added, modified or removed. - * Specific methods can refresh the cloudService definition and setup again the Cloud Client. + * Inner class defined to track the CloudServices as they get added, modified or + * removed. + * Specific methods can refresh the cloudService definition and setup again the + * Cloud Client. * */ private final class GPIOServiceTrackerCustomizer implements ServiceTrackerCustomizer { @@ -193,9 +197,10 @@ private void acquirePins() { if (this.gpioService != null) { logger.info("______________________________"); logger.info("Available GPIOs on the system:"); - Map gpios = this.gpioService.getAvailablePins(); - for (Entry e : gpios.entrySet()) { - logger.info("#{} - [{}]", e.getKey(), e.getValue()); + List gpioDescriptions = this.gpioService.getAvailablePinDescriptions(); + for (KuraGPIODescription desc : gpioDescriptions) { + logger.info("GPIO Pin Description: {}", desc.getDisplayName()); + logger.debug("GPIO Extended Pin Description: {}", desc.getProperties()); } logger.info("______________________________"); getPins(); @@ -209,41 +214,81 @@ private void getPins() { int[] triggers = this.gpioComponentOptions.getTriggers(); for (int i = 0; i < pins.length; i++) { try { - logger.info("Acquiring GPIO pin {} with params:", pins[i]); + String pin = pins[i]; + logger.info("Acquiring GPIO pin {} with params:", pin); logger.info(" Direction....: {}", directions[i]); logger.info(" Mode.........: {}", modes[i]); logger.info(" Trigger......: {}", triggers[i]); - KuraGPIOPin p = getPin(pins[i], getPinDirection(directions[i]), getPinMode(modes[i]), + List acquiredPins = getPins(pin, getPinDirection(directions[i]), getPinMode(modes[i]), getPinTrigger(triggers[i])); - if (p != null) { - p.open(); - logger.info("GPIO pin {} acquired", pins[i]); - if (p.getDirection() == KuraGPIODirection.OUTPUT) { - acquiredOutputPins.add(p); - } else { - acquiredInputPins.add(p); + acquiredPins.forEach(p -> { + try { + p.open(); + logger.info("GPIO pin {} acquired", pin); + if (p.getDirection() == KuraGPIODirection.OUTPUT) { + acquiredOutputPins.add(p); + } else { + acquiredInputPins.add(p); + } + } catch (IOException | KuraGPIODeviceException | KuraUnavailableDeviceException e) { + logger.error("I/O Error occurred!", e); } - } else { - logger.info("GPIO pin {} not found", pins[i]); - } - } catch (IOException e) { - logger.error("I/O Error occurred!", e); + }); } catch (Exception e) { - logger.error("got errror", e); + logger.error("got error", e); } } } - private KuraGPIOPin getPin(String resource, KuraGPIODirection pinDirection, KuraGPIOMode pinMode, + private List getPins(String resource, KuraGPIODirection pinDirection, KuraGPIOMode pinMode, KuraGPIOTrigger pinTrigger) { - KuraGPIOPin pin = null; + List pins = new ArrayList<>(); + // Resource can be terminal number, pin name or in the format + // pinName:controller:line. + // i.e. "1024" or "GPIO1_24" or "PIN:1:24" + // In the latter case, omitting a field or setting to * means all, i.e. ":1:24" + // or "PIN:*:24" or "PIN:1:" + String[] parts = resource.split(":"); try { - int terminal = Integer.parseInt(resource); - if (terminal > 0 && terminal < 1255) { - pin = this.gpioService.getPinByTerminal(Integer.parseInt(resource), pinDirection, pinMode, pinTrigger); + switch (parts.length) { + case 1: + KuraGPIOPin pin = getPinByNameOrTerminal(parts, pinDirection, pinMode, pinTrigger); + if (pin != null) { + pins.add(pin); + } + break; + case 3: + Map pinDescription = new HashMap<>(); + if (!parts[0].trim().isEmpty() && !parts[0].trim().equals("*")) { + pinDescription.put("name", parts[0].trim()); + } + if (!parts[1].trim().isEmpty() && !parts[1].trim().equals("*")) { + pinDescription.put("controller", parts[1].trim()); + } + if (!parts[2].trim().isEmpty() && !parts[2].trim().equals("*")) { + pinDescription.put("line", parts[2].trim()); + } + pins = this.gpioService.getPins(pinDescription, pinDirection, pinMode, + pinTrigger); + break; + default: + logger.error("Invalid GPIO pin resource format: {}", resource); + break; } + } catch (IllegalArgumentException e) { + logger.error("Invalid GPIO pin parameters!", e); + } + return pins; + } + + private KuraGPIOPin getPinByNameOrTerminal(String[] parts, KuraGPIODirection pinDirection, KuraGPIOMode pinMode, + KuraGPIOTrigger pinTrigger) { + KuraGPIOPin pin = null; + try { + int terminal = Integer.parseInt(parts[0].trim()); + pin = this.gpioService.getPinByTerminal(terminal, pinDirection, pinMode, pinTrigger); } catch (NumberFormatException e) { - pin = this.gpioService.getPinByName(resource, pinDirection, pinMode, pinTrigger); + pin = this.gpioService.getPinByName(parts[0].trim(), pinDirection, pinMode, pinTrigger); } return pin; } @@ -320,42 +365,42 @@ private void releasePins() { private KuraGPIODirection getPinDirection(int direction) { switch (direction) { - case 0, 2: - return KuraGPIODirection.INPUT; - case 1, 3: - return KuraGPIODirection.OUTPUT; - default: - return KuraGPIODirection.OUTPUT; + case 0, 2: + return KuraGPIODirection.INPUT; + case 1, 3: + return KuraGPIODirection.OUTPUT; + default: + return KuraGPIODirection.OUTPUT; } } private KuraGPIOMode getPinMode(int mode) { switch (mode) { - case 2: - return KuraGPIOMode.INPUT_PULL_DOWN; - case 1: - return KuraGPIOMode.INPUT_PULL_UP; - case 8: - return KuraGPIOMode.OUTPUT_OPEN_DRAIN; - case 4: - return KuraGPIOMode.OUTPUT_PUSH_PULL; - default: - return KuraGPIOMode.OUTPUT_OPEN_DRAIN; + case 2: + return KuraGPIOMode.INPUT_PULL_DOWN; + case 1: + return KuraGPIOMode.INPUT_PULL_UP; + case 8: + return KuraGPIOMode.OUTPUT_OPEN_DRAIN; + case 4: + return KuraGPIOMode.OUTPUT_PUSH_PULL; + default: + return KuraGPIOMode.OUTPUT_OPEN_DRAIN; } } private KuraGPIOTrigger getPinTrigger(int trigger) { switch (trigger) { - case 0: - return KuraGPIOTrigger.NONE; - case 2: - return KuraGPIOTrigger.RAISING_EDGE; - case 3: - return KuraGPIOTrigger.BOTH_EDGES; - case 1: - return KuraGPIOTrigger.FALLING_EDGE; - default: - return KuraGPIOTrigger.NONE; + case 0: + return KuraGPIOTrigger.NONE; + case 2: + return KuraGPIOTrigger.RAISING_EDGE; + case 3: + return KuraGPIOTrigger.BOTH_EDGES; + case 1: + return KuraGPIOTrigger.FALLING_EDGE; + default: + return KuraGPIOTrigger.NONE; } } diff --git a/kura-examples/bundles/gpio/org.eclipse.kura.example.gpio/src/main/java/org/eclipse/kura/example/gpio/GpioComponentOCD.java b/kura-examples/bundles/gpio/org.eclipse.kura.example.gpio/src/main/java/org/eclipse/kura/example/gpio/GpioComponentOCD.java index aeaccbf3..02dd298e 100644 --- a/kura-examples/bundles/gpio/org.eclipse.kura.example.gpio/src/main/java/org/eclipse/kura/example/gpio/GpioComponentOCD.java +++ b/kura-examples/bundles/gpio/org.eclipse.kura.example.gpio/src/main/java/org/eclipse/kura/example/gpio/GpioComponentOCD.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2025 Eurotech and/or its affiliates and others + * Copyright (c) 2025, 2026 Eurotech and/or its affiliates and others * * This program and the accompanying materials are made * available under the terms of the Eclipse Public License 2.0 @@ -20,75 +20,72 @@ @SuppressWarnings("checkstyle:MethodName") @ObjectClassDefinition( // - id = "org.eclipse.kura.example.gpio.GpioComponent", // - name = "GPIO Configuration", // - description = "Example of a GPIO Configuring Application." // + id = "org.eclipse.kura.example.gpio.GpioComponent", // + name = "GPIO Configuration", // + description = "Example of a GPIO Configuring Application." // ) @ComponentPropertyType public @interface GpioComponentOCD { - @AttributeDefinition(name = "Gpio Service Pid", // - description = "The Kura GPIO service to be used to interact with gpios.", // - required = true // - // - ) - String gpio_service_pid() default "org.eclipse.kura.gpio.GPIOService"; + @AttributeDefinition(name = "Gpio Service Pid", // + description = "The Kura GPIO service to be used to interact with gpios.", // + required = true // + ) + String gpio_service_pid() default "org.eclipse.kura.gpio.GPIOService"; - @AttributeDefinition(name = "Gpio Input Read Mode", // - description = "Specifies how input pin value is obtained. If set to PIN_STATUS_LISTENER, the pin value will be printed on the log on change, if set to POLLING, the pin value will be readed and printed on the log periodically.", // - required = true, // - options = { // - @Option(label = "PIN_STATUS_LISTENER", value = "PIN_STATUS_LISTENER"), // - @Option(label = "POLLING", value = "POLLING") // - }) - String gpio_input_read_mode() default "PIN_STATUS_LISTENER"; + @AttributeDefinition(name = "Gpio Input Read Mode", // + description = "Specifies how input pin value is obtained. If set to PIN_STATUS_LISTENER, the pin value will be printed on the log on change, if set to POLLING, the pin value will be readed and printed on the log periodically.", // + required = true, // + options = { // + @Option(label = "PIN_STATUS_LISTENER", value = "PIN_STATUS_LISTENER"), // + @Option(label = "POLLING", value = "POLLING") // + }) + String gpio_input_read_mode() default "PIN_STATUS_LISTENER"; - @AttributeDefinition(name = "Gpio Pins", // - description = "List of GPIO pins expressed as pin number or pin name (i.e. DOUT1, DIN1, ...).", // - required = false, // - cardinality = 5 // - ) - String[] gpio_pins() default {}; + @AttributeDefinition(name = "Gpio Pins", // + description = "List of GPIO pins expressed as pin number (i.e. 1022), pin name (i.e. DOUT1, DIN1, ...) or name:controller:line (i.e. GPIO1:0:24). " // + + "In the latter case, omitting a field or setting to * means all, i.e. \":1:24\" or \"PIN:*:24\" or \"PIN:1:\"", // + required = false, // + cardinality = 5 // + ) + String[] gpio_pins() default {}; - @AttributeDefinition(name = "Gpio Directions", // - description = "Pin directions", // - required = false, // - cardinality = 5, // - options = { // - @Option(label = "Only input", value = "0"), // - @Option(label = "Only output", value = "1"), // - @Option(label = "Both, init input", value = "2"), // - @Option(label = "Both, init output", value = "3") // - }) - int[] gpio_directions() default { 3, 3, 3, 3, 3 }; + @AttributeDefinition(name = "Gpio Directions", // + description = "Pin directions", // + required = false, // + cardinality = 5, // + options = { // + @Option(label = "Only input", value = "0"), // + @Option(label = "Only output", value = "1"), // + @Option(label = "Both, init input", value = "2"), // + @Option(label = "Both, init output", value = "3") // + }) + int[] gpio_directions() default { 3, 3, 3, 3, 3 }; - @AttributeDefinition(name = "Gpio Modes", // - description = "Pin working mode", // - required = false, // - cardinality = 5, // - options = { // - @Option(label = "Default", value = "-1"), // - @Option(label = "Input with Pull Down", value = "2"), // - @Option(label = "Input with Pull Up", value = "1"), // - @Option(label = "Open Drain Output", value = "8"), // - @Option(label = "Push-Pull Output", value = "4") // - }) - int[] gpio_modes() default { -1, -1, -1, -1, -1 }; + @AttributeDefinition(name = "Gpio Modes", // + description = "Pin working mode", // + required = false, // + cardinality = 5, // + options = { // + @Option(label = "Default", value = "-1"), // + @Option(label = "Input with Pull Down", value = "2"), // + @Option(label = "Input with Pull Up", value = "1"), // + @Option(label = "Open Drain Output", value = "8"), // + @Option(label = "Push-Pull Output", value = "4") // + }) + int[] gpio_modes() default { -1, -1, -1, -1, -1 }; - @AttributeDefinition(name = "Gpio Triggers", // - description = "Input triggering mode", // - required = false, // - cardinality = 5, // - options = { // - @Option(label = "Default", value = "-1"), // - @Option(label = "No trigger", value = "0"), // - @Option(label = "Rising edge", value = "2"), // - @Option(label = "Both edges", value = "3"), // - @Option(label = "Falling edge", value = "1") // - //