Search in sources :

Example 1 with FirmataFieldAnalog

use of org.apache.plc4x.java.firmata.readwrite.field.FirmataFieldAnalog in project plc4x by apache.

the class FirmataProtocolLogic method publishAnalogEvents.

protected void publishAnalogEvents(int pin, int value) {
    // Try sending the subscription event to all listeners.
    for (Map.Entry<DefaultPlcConsumerRegistration, Consumer<PlcSubscriptionEvent>> entry : consumers.entrySet()) {
        final DefaultPlcConsumerRegistration registration = entry.getKey();
        final Consumer<PlcSubscriptionEvent> consumer = entry.getValue();
        // Only if the current data point matches the subscription, publish the event to it.
        for (PlcSubscriptionHandle handle : registration.getSubscriptionHandles()) {
            if (handle instanceof FirmataSubscriptionHandle) {
                FirmataSubscriptionHandle subscriptionHandle = (FirmataSubscriptionHandle) handle;
                // (The bit subscribed to in this field actually changed).
                if (subscriptionHandle.getField() instanceof FirmataFieldAnalog) {
                    FirmataFieldAnalog analogField = (FirmataFieldAnalog) subscriptionHandle.getField();
                    // Check if this field would include the current pin.
                    if ((analogField.getAddress() <= pin) && (analogField.getAddress() + analogField.getNumberOfElements() >= pin)) {
                        // Build an update event containing the current values for all subscribed fields.
                        List<PlcValue> values = new ArrayList<>(analogField.getNumberOfElements());
                        for (int i = analogField.getAddress(); i < analogField.getAddress() + analogField.getNumberOfElements(); i++) {
                            if (analogValues.containsKey(i)) {
                                values.add(new PlcDINT(analogValues.get(i).intValue()));
                            } else // This could be the case if only some of the requested array values are available
                            {
                                values.add(new PlcDINT(-1));
                            }
                        }
                        sendUpdateEvents(consumer, subscriptionHandle.getName(), values);
                    }
                }
            }
        }
    }
}
Also used : DefaultPlcConsumerRegistration(org.apache.plc4x.java.spi.model.DefaultPlcConsumerRegistration) PlcDINT(org.apache.plc4x.java.spi.values.PlcDINT) PlcSubscriptionHandle(org.apache.plc4x.java.api.model.PlcSubscriptionHandle) FirmataSubscriptionHandle(org.apache.plc4x.java.firmata.readwrite.model.FirmataSubscriptionHandle) Consumer(java.util.function.Consumer) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) FirmataFieldAnalog(org.apache.plc4x.java.firmata.readwrite.field.FirmataFieldAnalog)

Example 2 with FirmataFieldAnalog

use of org.apache.plc4x.java.firmata.readwrite.field.FirmataFieldAnalog in project plc4x by apache.

the class FirmataDriverContext method processSubscriptionRequest.

public List<FirmataMessage> processSubscriptionRequest(PlcSubscriptionRequest subscriptionRequest) {
    // Convert the request into maps of bit sets.
    Map<Integer, PinMode> requestDigitalFieldPinModes = new HashMap<>();
    Map<Integer, PinMode> requestAnalogFieldPinModes = new HashMap<>();
    for (String fieldName : subscriptionRequest.getFieldNames()) {
        final PlcField field = subscriptionRequest.getField(fieldName);
        DefaultPlcSubscriptionField subscriptionField = (DefaultPlcSubscriptionField) field;
        if (subscriptionField.getPlcField() instanceof FirmataFieldDigital) {
            FirmataFieldDigital fieldDigital = (FirmataFieldDigital) subscriptionField.getPlcField();
            PinMode fieldPinMode = (fieldDigital.getPinMode() != null) ? fieldDigital.getPinMode() : PinMode.PinModeInput;
            if (!(fieldPinMode.equals(PinMode.PinModeInput) || fieldPinMode.equals(PinMode.PinModePullup))) {
                throw new PlcInvalidFieldException("Subscription field must be of type 'INPUT' (default) or 'PULLUP'");
            }
            for (int pin = fieldDigital.getAddress(); pin < fieldDigital.getAddress() + fieldDigital.getNumberOfElements(); pin++) {
                requestDigitalFieldPinModes.put(pin, fieldPinMode);
            }
        } else if (subscriptionField.getPlcField() instanceof FirmataFieldAnalog) {
            FirmataFieldAnalog fieldAnalog = (FirmataFieldAnalog) subscriptionField.getPlcField();
            for (int pin = fieldAnalog.getAddress(); pin < fieldAnalog.getAddress() + fieldAnalog.getNumberOfElements(); pin++) {
                requestAnalogFieldPinModes.put(pin, PinMode.PinModeInput);
            }
        } else {
            throw new PlcRuntimeException("Unsupported field type " + field.getClass().getSimpleName());
        }
    }
    // If a requested digital pin is already subscribed, blank this out
    for (Map.Entry<Integer, PinMode> entry : requestDigitalFieldPinModes.entrySet()) {
        int pin = entry.getKey();
        PinMode pinMode = entry.getValue();
        if (digitalPins.containsKey(pin)) {
            if (!digitalPins.get(pin).equals(pinMode)) {
                throw new PlcInvalidFieldException(String.format("Error setting digital pin to mode %s, pin is already set to mode %s", pinMode.toString(), digitalPins.get(pin).toString()));
            } else {
                requestDigitalFieldPinModes.remove(pin);
            }
        }
    }
    // If a requested analog pin is already subscribed, blank this out
    for (Map.Entry<Integer, PinMode> entry : requestAnalogFieldPinModes.entrySet()) {
        int pin = entry.getKey();
        if (analogPins.containsKey(pin)) {
            requestAnalogFieldPinModes.remove(pin);
        }
    }
    // Remember the subscription itself.
    subscriptions.add(subscriptionRequest);
    // Create a list of messages that need to be sent to achieve the desired subscriptions.
    List<FirmataMessage> messages = new LinkedList<>();
    for (Map.Entry<Integer, PinMode> entry : requestDigitalFieldPinModes.entrySet()) {
        int pin = entry.getKey();
        PinMode pinMode = entry.getValue();
        // Digital pins can be input and output, so first we have to set it to "input"
        messages.add(new FirmataMessageCommand(new FirmataCommandSetPinMode((byte) pin, pinMode, false), false));
        // And then tell the remote to send change of state information.
        messages.add(new FirmataMessageSubscribeDigitalPinValue((byte) pin, true, false));
    }
    for (Map.Entry<Integer, PinMode> entry : requestAnalogFieldPinModes.entrySet()) {
        int pin = entry.getKey();
        // Tell the remote to send change of state information for this analog pin.
        messages.add(new FirmataMessageSubscribeAnalogPinValue((byte) pin, true, false));
    }
    return messages;
}
Also used : PlcRuntimeException(org.apache.plc4x.java.api.exceptions.PlcRuntimeException) PlcField(org.apache.plc4x.java.api.model.PlcField) DefaultPlcSubscriptionField(org.apache.plc4x.java.spi.model.DefaultPlcSubscriptionField) PlcInvalidFieldException(org.apache.plc4x.java.api.exceptions.PlcInvalidFieldException) FirmataFieldDigital(org.apache.plc4x.java.firmata.readwrite.field.FirmataFieldDigital) FirmataFieldAnalog(org.apache.plc4x.java.firmata.readwrite.field.FirmataFieldAnalog)

Aggregations

FirmataFieldAnalog (org.apache.plc4x.java.firmata.readwrite.field.FirmataFieldAnalog)2 ConcurrentHashMap (java.util.concurrent.ConcurrentHashMap)1 Consumer (java.util.function.Consumer)1 PlcInvalidFieldException (org.apache.plc4x.java.api.exceptions.PlcInvalidFieldException)1 PlcRuntimeException (org.apache.plc4x.java.api.exceptions.PlcRuntimeException)1 PlcField (org.apache.plc4x.java.api.model.PlcField)1 PlcSubscriptionHandle (org.apache.plc4x.java.api.model.PlcSubscriptionHandle)1 FirmataFieldDigital (org.apache.plc4x.java.firmata.readwrite.field.FirmataFieldDigital)1 FirmataSubscriptionHandle (org.apache.plc4x.java.firmata.readwrite.model.FirmataSubscriptionHandle)1 DefaultPlcConsumerRegistration (org.apache.plc4x.java.spi.model.DefaultPlcConsumerRegistration)1 DefaultPlcSubscriptionField (org.apache.plc4x.java.spi.model.DefaultPlcSubscriptionField)1 PlcDINT (org.apache.plc4x.java.spi.values.PlcDINT)1