All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.pi4j.io.gpio.impl.GpioScheduledExecutorImpl Maven / Gradle / Ivy

Go to download

This bundle wraps Pi4j (http://pi4j.com) that wraps the native code Wiring Pi (http://wiringpi.com). It wraps these libraries to make them OSGi friendly and allow them to work together with the OSGi enRoute IoT circuit library (osgi.enroute.iot.circuit). The bundle will first use Pi4J to detect on what hardware it runs. If it runs on an appropriate type, it will register a component that can be configured with Metatype. The Metatype defines a full blown configuration template for all the Pi's functions. The GPIO's are registered as components for the circuit. Regardless of the success of the configuration, this bundle will also register a GpioController service, which is the main Pi4J class.

The newest version!
package com.pi4j.io.gpio.impl;

/*
 * #%L
 * **********************************************************************
 * ORGANIZATION  :  Pi4J
 * PROJECT       :  Pi4J :: Java Library (Core)
 * FILENAME      :  GpioScheduledExecutorImpl.java  
 * 
 * This file is part of the Pi4J project. More information about 
 * this project can be found here:  http://www.pi4j.com/
 * **********************************************************************
 * %%
 * Copyright (C) 2012 - 2015 Pi4J
 * %%
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as
 * published by the Free Software Foundation, either version 3 of the
 * License, or (at your option) any later version.
 * 
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Lesser Public License for more details.
 * 
 * You should have received a copy of the GNU General Lesser Public
 * License along with this program.  If not, see
 * .
 * #L%
 */


import com.pi4j.io.gpio.GpioFactory;
import com.pi4j.io.gpio.GpioPinDigitalOutput;
import com.pi4j.io.gpio.PinState;
import com.pi4j.io.gpio.tasks.impl.GpioBlinkStopTaskImpl;
import com.pi4j.io.gpio.tasks.impl.GpioBlinkTaskImpl;
import com.pi4j.io.gpio.tasks.impl.GpioPulseTaskImpl;

import java.util.ArrayList;
import java.util.Map.Entry;
import java.util.concurrent.*;

public class GpioScheduledExecutorImpl {

    private static final ConcurrentHashMap>> pinTaskQueue = new ConcurrentHashMap<>();
    private static ScheduledExecutorService scheduledExecutorService;

    private synchronized static void init(GpioPinDigitalOutput pin) {
        if (scheduledExecutorService == null) {
            scheduledExecutorService = GpioFactory.getExecutorServiceFactory().getScheduledExecutorService();
        }

        // determine if any existing future tasks are already scheduled for this pin
        if (pinTaskQueue.containsKey(pin)) {
            // if a task is found, then cancel all pending tasks immediately and remove them
            ArrayList> tasks = pinTaskQueue.get(pin);
            if (tasks != null && !tasks.isEmpty()) {
                for (int index =  (tasks.size() - 1); index >= 0; index--) {
                    ScheduledFuture task = tasks.get(index);
                    task.cancel(true);
                    tasks.remove(index);
                }
            }
            
            // if no remaining future tasks are remaining, then remove this pin from the tasks queue
            if (tasks != null && tasks.isEmpty()) {
                pinTaskQueue.remove(pin);
            }
        }
    }
    
    private synchronized static ScheduledFuture createCleanupTask(long delay) {
        // create future task to clean up completed tasks

        @SuppressWarnings({"rawtypes", "unchecked"})
        ScheduledFuture cleanupFutureTask = scheduledExecutorService.schedule(new Callable() {
            public Object call() throws Exception {
                for (Entry>> item : pinTaskQueue.entrySet()) {
                    ArrayList> remainingTasks = item.getValue();

                    // if a task is found, then cancel all pending tasks immediately and remove them
                    if (remainingTasks != null && !remainingTasks.isEmpty()) {
                        for (int index = (remainingTasks.size() - 1); index >= 0; index--) {
                            ScheduledFuture remainingTask = remainingTasks.get(index);
                            if (remainingTask.isCancelled() || remainingTask.isDone()) {
                                remainingTasks.remove(index);
                            }
                        }
                        
                        // if no remaining future tasks are remaining, then remove this pin from the tasks queue
                        if (remainingTasks.isEmpty()) {
                            pinTaskQueue.remove(item.getKey());
                        }
                    }
                }
                return null;
            }
        }, delay, TimeUnit.MILLISECONDS);
        
        return cleanupFutureTask;
    }

    public synchronized static Future pulse(GpioPinDigitalOutput pin, long duration, PinState pulseState) {
        return pulse(pin, duration, pulseState, null);
    }

    public synchronized static Future pulse(GpioPinDigitalOutput pin, long duration, PinState pulseState, Callable callback) {
        
        // create future return object
        ScheduledFuture scheduledFuture = null; 
                
        // perform the initial startup and cleanup for this pin 
        init(pin);

        // we only pulse for requests with a valid duration in milliseconds
        if (duration > 0) {
            // set the active state
            pin.setState(pulseState);
            
            // create future job to return the pin to the low state
            scheduledFuture = scheduledExecutorService
                .schedule(new GpioPulseTaskImpl(pin, PinState.getInverseState(pulseState), callback), duration, TimeUnit.MILLISECONDS);

            // get pending tasks for the current pin
            ArrayList> tasks;
            if (!pinTaskQueue.containsKey(pin)) {
                pinTaskQueue.put(pin, new ArrayList>());
            }
            tasks = pinTaskQueue.get(pin);
            
            // add the new scheduled task to the tasks collection
            tasks.add(scheduledFuture);
            
            // create future task to clean up completed tasks
            createCleanupTask(duration + 500);
        }

        // return future task
        return scheduledFuture;
    }

    public synchronized static Future blink(GpioPinDigitalOutput pin, long delay, long duration, PinState blinkState) {

        // perform the initial startup and cleanup for this pin 
        init(pin);
        
        // we only blink for requests with a valid delay in milliseconds
        if (delay > 0) {
            // make sure pin starts in active state
            pin.setState(blinkState);
            
            // create future job to toggle the pin state
            ScheduledFuture scheduledFutureBlinkTask = scheduledExecutorService
                .scheduleAtFixedRate(new GpioBlinkTaskImpl(pin), delay, delay, TimeUnit.MILLISECONDS);
                
            // get pending tasks for the current pin
            ArrayList> tasks;
            if (!pinTaskQueue.containsKey(pin)) {
                pinTaskQueue.put(pin, new ArrayList>());
            }
            tasks = pinTaskQueue.get(pin);

            // add the new scheduled task to the tasks collection
            tasks.add(scheduledFutureBlinkTask);

            // if a duration was defined, then schedule a future task to kill the blinker task
            if (duration > 0) {
                // create future job to stop blinking
                ScheduledFuture scheduledFutureBlinkStopTask = scheduledExecutorService
                    .schedule(new GpioBlinkStopTaskImpl(pin,PinState.getInverseState(blinkState), scheduledFutureBlinkTask), duration, TimeUnit.MILLISECONDS);

                // add the new scheduled stop task to the tasks collection
                tasks.add(scheduledFutureBlinkStopTask);

                // create future task to clean up completed tasks
                createCleanupTask(duration + 500);                
            }      

            // return future task
            return scheduledFutureBlinkTask;
        }
        
        // no future task when a delay time has not been specified
        return null;
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy