org.openhab.binding.IEEE1888.server.FIAPServer.java Source code

Java tutorial

Introduction

Here is the source code for org.openhab.binding.IEEE1888.server.FIAPServer.java

Source

/**
 * Copyright (c) 2010-2016, openHAB.org and others.
 *
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 */

package org.openhab.binding.IEEE1888.server;

import org.apache.axis2.databinding.types.URI;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.time.DateFormatUtils;
import org.apache.commons.lang3.time.DateUtils;
import org.fiap.server.FIAPServerInterface;
import org.fiap.soap.DataRQ;
import org.fiap.soap.DataRS;
import org.fiap.soap.QueryRQ;
import org.fiap.soap.QueryRS;
import org.fiap.types.Body;
import org.fiap.types.Error;
import org.fiap.types.Header;
import org.fiap.types.Key;
import org.fiap.types.OK;
import org.fiap.types.Point;
import org.fiap.types.PointSet;
import org.fiap.types.Query;
import org.fiap.types.Transport;
import org.fiap.types.TrapType;
import org.fiap.types.Value;
import org.openhab.binding.IEEE1888.internal.IEEE1888Binding;
import org.openhab.binding.IEEE1888.trap.TrapManager;
import org.openhab.core.items.Item;
import org.openhab.core.items.ItemNotFoundException;
import org.openhab.core.types.Command;
import org.openhab.core.types.State;
import org.openhab.core.types.TypeParser;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.text.ParseException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * <p>
 * IEEE1888 WebService Server
 * </p>
 *
 * @author Kazuhiro Matsuda
 * @since 1.8.0
 */
public class FIAPServer implements FIAPServerInterface {
    /**
     * logger 
     */
    private static final Logger logger = LoggerFactory.getLogger(IEEE1888Binding.class);
    private static final String TIME_FORMAT = "yyyy-MM-dd HH:mm:ss.SSS";
    private static final Pattern STATE_CONFIG_PATTERN = Pattern.compile("(.*?)\\=(.*?)\\&(.*?)\\=(.*?)");

    public QueryRS query(QueryRQ queryRQ) {
        try {
            Query query = queryRQ.getTransport().getHeader().getQuery();
            URI callbackData = query.getCallbackData();

            Key[] keys = query.getKey();

            Body body = new Body();
            if (ArrayUtils.isNotEmpty(keys)) {
                for (Key key : keys) {
                    if (!("time".equals(key.getAttrName()) && "maximum".equals(key.getSelect()))) {
                        Error error = new Error();
                        error.setString("query for past data is not supported.");
                        error.setType("QUERY_NOT_SUPPORTED");
                        return buildQueryRS(null, null, error);
                    }

                    URI id = key.getId();
                    String itemName = buildItemName(id);
                    Item item = IEEE1888Binding.getItemRegistry().getItem(itemName);
                    String stateStr = item.getState().toString();

                    if (item != null) {
                        String value = item.getState().toString();
                        // create point value
                        Point point = buidPoint(id, value);
                        body.addPoint(point);

                        // trap
                        if (key.getTrap() == TrapType.changed && callbackData != null) {
                            TrapManager.addTrap(itemName, point, callbackData.toString());
                        }

                        State state = TypeParser.parseState(item.getAcceptedDataTypes(), stateStr);
                        IEEE1888Binding.getEventPublisher().postUpdate(itemName, state);
                        logger.debug("state from FIAP service Binding: " + "itemName : " + itemName + " state : "
                                + state.toString());
                    }
                }
            }
            return buildQueryRS(query, body, null);

        } catch (Exception e) {
            Error error = new Error();
            error.setString(e.getMessage());
            error.setType("SERVER_ERROR");
            return buildQueryRS(null, null, error);
        }
    }

    private Point buidPoint(URI id, String valueStr) throws ParseException {
        // analyze value
        HashMap<String, String> keyValueMap = new HashMap<>();
        if (valueStr != null) {
            String[] values = StringUtils.split(valueStr, "&");
            if (values != null) {
                for (String value : values) {
                    keyValueMap.put(StringUtils.substringBefore(value, "="),
                            StringUtils.substringAfter(value, "="));
                }
            }
        }
        // [point]
        Point point = new Point();
        point.setId(id);

        Value value = new Value();
        // [time]
        Calendar timeValue = Calendar.getInstance();
        if (StringUtils.isNotBlank(keyValueMap.get("time"))) {
            Date dateTime = DateUtils.parseDate(keyValueMap.get("time"), TIME_FORMAT);
            timeValue.setTime(dateTime);
        }
        value.setTime(timeValue);

        // [value]
        String v;
        if (keyValueMap.containsKey("value")) {
            v = keyValueMap.get("value");
        } else {
            v = valueStr;
        }
        if (v == null) {
            v = "";
        }
        value.setString(v);

        point.addValue(value);
        return point;
    }

    private QueryRS buildQueryRS(Query query, Body body, Error error) {
        QueryRS queryRS = new QueryRS();
        // header
        Header header = new Header();
        if (error != null) {
            header.setError(error);
        } else {
            header.setOK(new OK());
            header.setQuery(query);
        }

        // Transport
        Transport transport = new Transport();
        transport.setHeader(header);

        if (error == null) {
            transport.setBody(body);
        }

        queryRS.setTransport(transport);
        return queryRS;
    }

    public DataRS data(DataRQ dataRQ) {
        try {
            // [point]
            Point[] points = dataRQ.getTransport().getBody().getPoint();
            sendPointsData(points);

            // [point set]
            PointSet[] pointSets = dataRQ.getTransport().getBody().getPointSet();
            sendPointSetsData(pointSets);

            // return OK
            return buildDataRS(null);
        } catch (Exception e) {
            Error error = new Error();
            error.setString(StringUtils.defaultString(e.getMessage()));
            error.setType("SERVER_ERROR");
            return buildDataRS(error);
        }
    }

    private void sendPointSetsData(PointSet[] pointSets) throws ItemNotFoundException {
        if (ArrayUtils.isEmpty(pointSets)) {
            return;
        }
        for (PointSet pointSet : pointSets) {
            sendPointsData(pointSet.getPoint());
            PointSet[] subPointSets = pointSet.getPointSet();
            if (ArrayUtils.isNotEmpty(subPointSets)) {
                sendPointSetsData(subPointSets);
            }
        }
    }

    private void sendPointsData(Point[] points) throws ItemNotFoundException {
        if (ArrayUtils.isNotEmpty(points)) {
            for (Point point : points) {
                // [value]
                Value[] value = point.getValue();
                if (ArrayUtils.isEmpty(value)) {
                    continue;
                }

                String itemName = buildItemName(point.getId());

                for (Value v : value) {
                    String valueStr = v.getString();
                    Calendar valueTime = v.getTime();
                    Item item = IEEE1888Binding.getItemRegistry().getItem(itemName);
                    String oldItemValue = item.getState().toString();

                    // send command
                    String valueTimeStr = DateFormatUtils.format(valueTime, TIME_FORMAT);

                    List<String> buildCmd = new ArrayList<>();
                    buildCmd.add("time=" + valueTimeStr);
                    buildCmd.add("value=" + valueStr);
                    String cmdStr = StringUtils.join(buildCmd, "&");

                    Command cmd = TypeParser.parseCommand(item.getAcceptedCommandTypes(), cmdStr);
                    if (cmd != null) {
                        IEEE1888Binding.getEventPublisher().postCommand(itemName, cmd);
                        logger.debug("command from FIAP service Binding: \n" + "itemName : " + itemName
                                + "\n cmd : " + cmd.toString());
                    }

                    if (oldItemValue != null) {
                        // analyze state
                        Matcher matcher = STATE_CONFIG_PATTERN.matcher(oldItemValue);
                        // update state
                        if (matcher.find()) {
                            valueStr = cmdStr;
                        }
                    }
                    State state = TypeParser.parseState(item.getAcceptedDataTypes(), valueStr);
                    // following five lines may not be needed.
                    if (state != null) {
                        IEEE1888Binding.getEventPublisher().postUpdate(itemName, state);
                        logger.debug("state from FIAP service Binding: \n" + "itemName : " + itemName + "\n cmd : "
                                + state.toString());
                    }
                }
            }
        }
    }

    private String buildItemName(URI id) {
        String host = id.getHost();
        String path = id.getPath();

        if (StringUtils.isBlank(host)) {
            host = id.getRegBasedAuthority();
        }

        List<String> subNameList = new ArrayList<>();

        subNameList.add(host);

        if (StringUtils.isNotBlank(path)) {
            subNameList.addAll(Arrays.asList(StringUtils.split(path, "/")));
        }

        return StringUtils.join(subNameList, "_");
    }

    private DataRS buildDataRS(Error error) {
        DataRS dataRS = new DataRS();
        // header
        Header header = new Header();
        if (error != null) {
            header.setError(error);
        } else {
            header.setOK(new OK());
        }
        // Transport
        Transport transport = new Transport();
        transport.setHeader(header);

        dataRS.setTransport(transport);
        return dataRS;
    }
}