Search in sources :

Example 1 with StateServiceResponse

use of org.eclipse.smarthome.binding.lifx.internal.protocol.StateServiceResponse in project smarthome by eclipse.

the class LifxLightDiscovery method handlePacket.

private void handlePacket(Packet packet, InetSocketAddress address) {
    logger.trace("Discovery : Packet type '{}' received from '{}' for '{}' with sequence '{}' and source '{}'", new Object[] { packet.getClass().getSimpleName(), address.toString(), packet.getTarget().getHex(), packet.getSequence(), Long.toString(packet.getSource(), 16) });
    if (packet.getSource() == sourceId || packet.getSource() == 0) {
        MACAddress macAddress = packet.getTarget();
        DiscoveredLight light = discoveredLights.get(macAddress);
        if (packet instanceof StateServiceResponse) {
            int port = (int) ((StateServiceResponse) packet).getPort();
            if (port != 0) {
                try {
                    InetSocketAddress socketAddress = new InetSocketAddress(address.getAddress(), port);
                    if (light == null || (!socketAddress.equals(light.socketAddress))) {
                        if (light != null) {
                            light.cancelUnicastKey();
                        }
                        Selector lightSelector = selector;
                        if (lightSelector != null) {
                            String logId = getLogId(macAddress, socketAddress);
                            light = new DiscoveredLight(lightSelector, macAddress, socketAddress, logId, openUnicastChannel(lightSelector, logId, socketAddress));
                            discoveredLights.put(macAddress, light);
                        }
                    }
                } catch (Exception e) {
                    logger.warn("{} while connecting to IP address: {}", e.getClass().getSimpleName(), e.getMessage());
                    return;
                }
            }
        } else if (light != null) {
            if (packet instanceof StateLabelResponse) {
                light.label = ((StateLabelResponse) packet).getLabel().trim();
            } else if (packet instanceof StateVersionResponse) {
                try {
                    light.product = Products.getProductFromProductID(((StateVersionResponse) packet).getProduct());
                    light.productVersion = ((StateVersionResponse) packet).getVersion();
                } catch (IllegalArgumentException e) {
                    logger.debug("Discovered an unsupported light ({}): {}", light.macAddress.getAsLabel(), e.getMessage());
                    light.supportedProduct = false;
                }
            }
        }
        if (light != null && light.isDataComplete()) {
            try {
                thingDiscovered(createDiscoveryResult(light));
            } catch (IllegalArgumentException e) {
                logger.trace("{} while creating discovery result of light ({})", e.getClass().getSimpleName(), light.logId, e);
            }
        }
    }
}
Also used : MACAddress(org.eclipse.smarthome.binding.lifx.internal.fields.MACAddress) InetSocketAddress(java.net.InetSocketAddress) StateLabelResponse(org.eclipse.smarthome.binding.lifx.internal.protocol.StateLabelResponse) StateServiceResponse(org.eclipse.smarthome.binding.lifx.internal.protocol.StateServiceResponse) StateVersionResponse(org.eclipse.smarthome.binding.lifx.internal.protocol.StateVersionResponse) Selector(java.nio.channels.Selector)

Example 2 with StateServiceResponse

use of org.eclipse.smarthome.binding.lifx.internal.protocol.StateServiceResponse in project smarthome by eclipse.

the class LifxLightCommunicationHandler method handlePacket.

private void handlePacket(Packet packet, InetSocketAddress address) {
    boolean packetFromConfiguredMAC = macAddress != null && (packet.getTarget().equals(macAddress));
    boolean packetFromConfiguredHost = host != null && (address.equals(host));
    boolean broadcastPacket = packet.getTarget().equals(BROADCAST_ADDRESS);
    boolean packetSourceIsHandler = (packet.getSource() == sourceId || packet.getSource() == 0);
    if ((packetFromConfiguredMAC || packetFromConfiguredHost || broadcastPacket) && packetSourceIsHandler) {
        logger.trace("{} : Packet type '{}' received from '{}' for '{}' with sequence '{}' and source '{}'", new Object[] { logId, packet.getClass().getSimpleName(), address.toString(), packet.getTarget().getHex(), packet.getSequence(), Long.toString(packet.getSource(), 16) });
        if (packet instanceof StateServiceResponse) {
            StateServiceResponse response = (StateServiceResponse) packet;
            MACAddress discoveredAddress = response.getTarget();
            if (packetFromConfiguredHost && macAddress == null) {
                macAddress = discoveredAddress;
                selectorContext.setMACAddress(macAddress);
                currentLightState.setOnline(discoveredAddress);
                return;
            } else if (macAddress != null && macAddress.equals(discoveredAddress)) {
                boolean newHost = host == null || !address.equals(host);
                boolean newPort = unicastPort != (int) response.getPort();
                boolean newService = service != response.getService();
                if (newHost || newPort || newService || currentLightState.isOffline()) {
                    this.unicastPort = (int) response.getPort();
                    this.service = response.getService();
                    if (unicastPort == 0) {
                        logger.warn("Light ({}) service with ID '{}' is currently not available", logId, service);
                        currentLightState.setOfflineByCommunicationError();
                    } else {
                        this.host = new InetSocketAddress(address.getAddress(), unicastPort);
                        try {
                            cancelKey(unicastKey, logId);
                            unicastKey = openUnicastChannel(selector, logId, host);
                            selectorContext.setHost(host);
                            selectorContext.setUnicastKey(unicastKey);
                        } catch (IOException e) {
                            logger.warn("{} while opening the unicast channel of the light ({}): {}", e.getClass().getSimpleName(), logId, e.getMessage());
                            currentLightState.setOfflineByCommunicationError();
                            return;
                        }
                        currentLightState.setOnline();
                    }
                }
            }
        }
        // Listeners are notified in a separate thread for better concurrency and to prevent deadlock.
        scheduler.schedule(() -> {
            responsePacketListeners.forEach(listener -> listener.handleResponsePacket(packet));
        }, 0, TimeUnit.MILLISECONDS);
    }
}
Also used : MACAddress(org.eclipse.smarthome.binding.lifx.internal.fields.MACAddress) InetSocketAddress(java.net.InetSocketAddress) StateServiceResponse(org.eclipse.smarthome.binding.lifx.internal.protocol.StateServiceResponse) IOException(java.io.IOException)

Aggregations

InetSocketAddress (java.net.InetSocketAddress)2 MACAddress (org.eclipse.smarthome.binding.lifx.internal.fields.MACAddress)2 StateServiceResponse (org.eclipse.smarthome.binding.lifx.internal.protocol.StateServiceResponse)2 IOException (java.io.IOException)1 Selector (java.nio.channels.Selector)1 StateLabelResponse (org.eclipse.smarthome.binding.lifx.internal.protocol.StateLabelResponse)1 StateVersionResponse (org.eclipse.smarthome.binding.lifx.internal.protocol.StateVersionResponse)1