如何在GpioPinListenerDigital(Pi4J / RaspberryPi)中调用Web服务?

时间:2015-09-22 09:32:12

标签: java web-services raspberry-pi

当我的PIR传感器处于活动状态时,我想打电话给网络服务。 我用wsimport创建了web服务调用: wsimport -keep -s src http://webservicex.net/geoipservice.asmx?WSDL

我使用pi4j(http://pi4j.com/)项目库为我的Raspberry Pi编写了一个测试应用程序。在此代码中,在启动时调用服务,并在PIR传感器gettig激活时再次调用。 第一个调用是正确的,但是当我尝试调用GpioPinListenerDigital对象的handleGpioPinDigitalStateChangeEvent方法时,我得到了一个N​​ullPointerException。

package me.losadrian.Pirel;

import com.pi4j.io.gpio.GpioController;
import com.pi4j.io.gpio.GpioFactory;
import com.pi4j.io.gpio.GpioPinDigitalInput;
import com.pi4j.io.gpio.GpioPinDigitalOutput;
import com.pi4j.io.gpio.PinPullResistance;
import com.pi4j.io.gpio.PinState;
import com.pi4j.io.gpio.RaspiPin;
import com.pi4j.io.gpio.event.GpioPinDigitalStateChangeEvent;
import com.pi4j.io.gpio.event.GpioPinListenerDigital;

import net.webservicex.GeoIP;
import net.webservicex.GeoIPService;
import net.webservicex.GeoIPServiceSoap;

public class App {
    public static void main(String[] args) {

        GeoIPService service = new GeoIPService();
        GeoIPServiceSoap client = service.getGeoIPServiceSoap();
        GeoIP geoIp = client.getGeoIP("74.125.239.142");
        System.out.println(geoIp.getCountryName());

        final GpioController gpioPIR = GpioFactory.getInstance();
        final GpioPinDigitalInput sensorPir = gpioPIR.provisionDigitalInputPin(RaspiPin.GPIO_07, PinPullResistance.PULL_DOWN);

        final GpioController gpioREL1 = GpioFactory.getInstance();           
        final GpioPinDigitalOutput rel1 = gpioREL1.provisionDigitalOutputPin(RaspiPin.GPIO_08, "REL", PinState.HIGH);         
        final GpioController gpioREL2 = GpioFactory.getInstance();           
        final GpioPinDigitalOutput rel2 = gpioREL2.provisionDigitalOutputPin(RaspiPin.GPIO_09, "REL", PinState.HIGH);         

        rel1.high();
        rel2.high();

        sensorPir.addListener(new GpioPinListenerDigital() {

            public void handleGpioPinDigitalStateChangeEvent(GpioPinDigitalStateChangeEvent event) {
                if (event.getState().isHigh()) {
                    System.out.println("Motion!!");
                    GeoIPService service = new GeoIPService();
                    GeoIPServiceSoap client = service.getGeoIPServiceSoap();
                    GeoIP geoIp = client.getGeoIP("74.125.239.142");
                    System.out.println(geoIp.getCountryName());
                    rel1.low();
                    rel2.high();
                }
                if (event.getState().isLow()) {
                    System.out.println("Quiet...");
                    rel1.high();
                    rel2.low();
                }
            }
        });

        try {
            for (;;) {
                Thread.sleep(3000);
            }
        } catch (final Exception e) {
            System.out.println(e.getMessage());
        }

    }
}

控制台输出是:

pi@raspberrypi ~ $ sudo java -jar Pirel.jar 
United States
Motion!!
Exception in thread "pi4j-gpio-event-executor-0" java.lang.NullPointerException
    at com.sun.xml.internal.ws.client.ClientContainer$1.getResource(ClientContainer.java:45)
    at com.sun.xml.internal.ws.assembler.MetroConfigLoader.locateResource(MetroConfigLoader.java:220)
    at com.sun.xml.internal.ws.assembler.MetroConfigLoader.locateResource(MetroConfigLoader.java:230)
    at com.sun.xml.internal.ws.assembler.MetroConfigLoader.init(MetroConfigLoader.java:125)
    at com.sun.xml.internal.ws.assembler.MetroConfigLoader.<init>(MetroConfigLoader.java:104)
    at com.sun.xml.internal.ws.assembler.TubelineAssemblyController.getTubeCreators(TubelineAssemblyController.java:78)
    at com.sun.xml.internal.ws.assembler.MetroTubelineAssembler.createClient(MetroTubelineAssembler.java:103)
    at com.sun.xml.internal.ws.client.Stub.createPipeline(Stub.java:328)
    at com.sun.xml.internal.ws.client.Stub.<init>(Stub.java:295)
    at com.sun.xml.internal.ws.client.Stub.<init>(Stub.java:228)
    at com.sun.xml.internal.ws.client.Stub.<init>(Stub.java:243)
    at com.sun.xml.internal.ws.client.sei.SEIStub.<init>(SEIStub.java:84)
    at com.sun.xml.internal.ws.client.WSServiceDelegate.getStubHandler(WSServiceDelegate.java:814)
    at com.sun.xml.internal.ws.client.WSServiceDelegate.createEndpointIFBaseProxy(WSServiceDelegate.java:803)
    at com.sun.xml.internal.ws.client.WSServiceDelegate.getPort(WSServiceDelegate.java:436)
    at com.sun.xml.internal.ws.client.WSServiceDelegate.getPort(WSServiceDelegate.java:404)
    at com.sun.xml.internal.ws.client.WSServiceDelegate.getPort(WSServiceDelegate.java:386)
    at javax.xml.ws.Service.getPort(Service.java:119)
    at net.webservicex.GeoIPService.getGeoIPServiceSoap(GeoIPService.java:72)
    at me.losadrian.Pirel.App$1.handleGpioPinDigitalStateChangeEvent(App.java:42)
    at com.pi4j.io.gpio.tasks.impl.GpioEventDispatchTaskImpl.run(GpioEventDispatchTaskImpl.java:66)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    at java.lang.Thread.run(Thread.java:744)
Quiet...

有人知道如何更改此代码吗? 提前感谢您提供的任何帮助。

1 个答案:

答案 0 :(得分:1)

也许我找到了解决方案:

  • 如果我创建静态GeoIPService和GeoIPServiceSoap类变量,则服务调用有效。
  • 如果我在主要处理程序之前创建最终的GeoIPServiceSoap局部变量,则服务调用有效。

package me.losadrian.Pirel;

import com.pi4j.io.gpio.GpioController;
import com.pi4j.io.gpio.GpioFactory;
import com.pi4j.io.gpio.GpioPinDigitalInput;
import com.pi4j.io.gpio.GpioPinDigitalOutput;
import com.pi4j.io.gpio.PinPullResistance;
import com.pi4j.io.gpio.PinState;
import com.pi4j.io.gpio.RaspiPin;
import com.pi4j.io.gpio.event.GpioPinDigitalStateChangeEvent;
import com.pi4j.io.gpio.event.GpioPinListenerDigital;

import net.webservicex.GeoIP;
import net.webservicex.GeoIPService;
import net.webservicex.GeoIPServiceSoap;

public class App {
// Works here
//  static GeoIPService service = new GeoIPService();
//  static GeoIPServiceSoap client = service.getGeoIPServiceSoap();

    public static void main(String[] args) {
        // Works here too
        GeoIPService service = new GeoIPService();
        final GeoIPServiceSoap client = service.getGeoIPServiceSoap();

        final GpioController gpioPIR = GpioFactory.getInstance();
        final GpioPinDigitalInput sensorPir = gpioPIR.provisionDigitalInputPin(RaspiPin.GPIO_07, PinPullResistance.PULL_DOWN);

        final GpioController gpioREL1 = GpioFactory.getInstance();           
        final GpioPinDigitalOutput rel1 = gpioREL1.provisionDigitalOutputPin(RaspiPin.GPIO_08, "REL", PinState.HIGH);         
        final GpioController gpioREL2 = GpioFactory.getInstance();           
        final GpioPinDigitalOutput rel2 = gpioREL2.provisionDigitalOutputPin(RaspiPin.GPIO_09, "REL", PinState.HIGH);         

        rel1.high();
        rel2.high();

        sensorPir.addListener(new GpioPinListenerDigital() {

            public void handleGpioPinDigitalStateChangeEvent(GpioPinDigitalStateChangeEvent event) {
                if (event.getState().isHigh()) {
                    System.out.println("Motion!!");
// Not works here
//                  GeoIPService service = new GeoIPService();
//                  GeoIPServiceSoap client = service.getGeoIPServiceSoap();
                    GeoIP geoIp = client.getGeoIP("212.58.246.92");
                    System.out.println(geoIp.getCountryName());
                    rel1.low();
                    rel2.high();
                }
                if (event.getState().isLow()) {
                    System.out.println("Quiet...");
                    rel1.high();
                    rel2.low();
                }
            }
        });

        try {
            for (;;) {
                Thread.sleep(3000);
            }
        } catch (final Exception e) {
            System.out.println(e.getMessage());
        }

    }
}