public class DeviceHistoryData {
    @SerializedName("id")
    private Long mId;
    @SerializedName("l")
    private String mLevel;

    public DeviceHistoryData() {
        mId = -1l;
        mLevel = "";
    }

    public Long getId() {
        if (mId == null) {
            mId = -1l;
        }
        return mId;
    }

    public void setId(Long id) {
        this.mId = id;
    }

    public String getLevel() {
        if (mLevel == null) {
            mLevel = "";
        }
        return mLevel;
    }

    public void setLevel(String level) {
        this.mLevel = level;
    }

    /*
     * (non-Javadoc)
     *
     * @see java.lang.Object#toString()
     */
    @Override
    public String toString() {
        return new ToStringBuilder(this).append("id", mId).append("level", mLevel).toString();
    }
} public class DeviceHistoryList {
    private List<DeviceHistory> mDeviceHistoryList;

    /**
     * Instantiate a device history list with default values.
     */
    public DeviceHistoryList() {
        mDeviceHistoryList = new ArrayList<DeviceHistory>();
    }

    public void addDeviceHistory(DeviceHistory deviceHistory) {
        mDeviceHistoryList.add(deviceHistory);
    }

    public List<DeviceHistory> getDeviceHistoryList() {
        return mDeviceHistoryList;
    }

    /**
     * Return the first occurrence of device history
     *
     * @param id ZAutomation device id
     * @return device history or null if not found
     */
    public DeviceHistory getDeviceHistoryByDeviceId(String deviceId) {
        for (DeviceHistory deviceHistory : mDeviceHistoryList) {
            if (deviceHistory.getDeviceId().equals(deviceId)) {
                return deviceHistory;
            }
        }
        return null;
    }

    /*
     * (non-Javadoc)
     *
     * @see java.lang.Object#toString()
     */
    @Override
    public String toString() {
        ToStringBuilder toStringBuilder = new ToStringBuilder(this);
        for (DeviceHistory deviceHistory : mDeviceHistoryList) {
            toStringBuilder.append(deviceHistory);
        }

        return new ToStringBuilder(this).append("deviceHistoryList", toStringBuilder.toString()).toString();
    }
} public abstract class Device {
    private transient Logger logger = LoggerFactory.getLogger(this.getClass());

    @SerializedName("creationTime")
    private Integer mCreationTime;
    @SerializedName("creatorId")
    private Integer mCreatorId;
    @SerializedName("deviceType")
    private String mDeviceType;
    @SerializedName("h")
    private Integer mH;
    @SerializedName("hasHistory")
    private Boolean mHasHistory;
    @SerializedName("id")
    private String mDeviceId;
    @SerializedName("location")
    private Integer mLocation;
    @SerializedName("permanently_hidden")
    private Boolean mPermanentlyHidden;
    @SerializedName("probeType")
    private String mProbeType;
    @SerializedName("visibility")
    private Boolean mVisibility;
    @SerializedName("updateTime")
    private Integer mUpdateTime;

    @SerializedName("metrics")
    private Metrics mMetrics;
    @SerializedName("tags")
    private List<String> mTags;

    @SerializedName("customIcons")
    private Icons mCustomIcons;

    // Transient exclude field from serialization!
    protected transient IDeviceCommands mCommandHandler;

    /**
     * Instantiate a device with default values.
     */
    public Device() {
        mCreationTime = -1;
        mCreatorId = -1;
        mDeviceType = "";
        mH = -1;
        mHasHistory = false;
        mDeviceId = "";
        mLocation = -1;
        mPermanentlyHidden = false;
        mProbeType = "";
        mVisibility = false;
        mUpdateTime = -1;

        mMetrics = new Metrics();
        mTags = new ArrayList<String>();

        mCustomIcons = new Icons();
    }

    public Integer getCreationTime() {
        if (mCreationTime == null) {
            mCreationTime = -1;
        }
        return mCreationTime;
    }

    public void setCreationTime(Integer creationTime) {
        this.mCreationTime = creationTime;
    }

    public Integer getCreatorId() {
        if (mCreatorId == null) {
            mCreatorId = -1;
        }
        return mCreatorId;
    }

    public void setCreatorId(Integer creatorId) {
        this.mCreatorId = creatorId;
    }

    public String getDeviceType() {
        if (mDeviceType == null) {
            mDeviceType = "";
        }
        return mDeviceType;
    }

    public void setDeviceType(String deviceType) {
        this.mDeviceType = deviceType;
    }

    public Integer getH() {
        if (mH == null) {
            mH = -1;
        }
        return mH;
    }

    public void setH(Integer h) {
        this.mH = h;
    }

    public Boolean getHasHistory() {
        if (mHasHistory == null) {
            mHasHistory = false;
        }
        return mHasHistory;
    }

    public void setHasHistory(Boolean hasHistory) {
        this.mHasHistory = hasHistory;
    }

    public String getDeviceId() {
        if (mDeviceId == null) {
            mDeviceId = "";
        }
        return mDeviceId;
    }

    public void setDeviceId(String deviceId) {
        this.mDeviceId = deviceId;
    }

    public Integer getLocation() {
        if (mLocation == null) {
            mLocation = -1;
        }
        return mLocation;
    }

    public void setLocation(Integer location) {
        this.mLocation = location;
    }

    public Boolean getPermanentlyHidden() {
        if (mPermanentlyHidden == null) {
            mPermanentlyHidden = false;
        }
        return mPermanentlyHidden;
    }

    public void setPermanentlyHidden(Boolean permanently_hidden) {
        this.mPermanentlyHidden = permanently_hidden;
    }

    public String getProbeType() {
        if (mProbeType == null) {
            mProbeType = "";
        }
        return mProbeType;
    }

    public void setProbeType(String probeType) {
        this.mProbeType = probeType;
    }

    public Boolean getVisibility() {
        if (mVisibility == null) {
            mVisibility = false;
        }
        return mVisibility;
    }

    public void setVisibility(Boolean visability) {
        this.mVisibility = visability;
    }

    public Integer getUpdateTime() {
        if (mUpdateTime == null) {
            mUpdateTime = -1;
        }
        return mUpdateTime;
    }

    public void setUpdateTime(Integer updateTime) {
        this.mUpdateTime = updateTime;
    }

    public Metrics getMetrics() {
        if (mMetrics == null) {
            mMetrics = new Metrics();
        }
        return mMetrics;
    }

    public void setMetrics(Metrics metrics) {
        this.mMetrics = metrics;
    }

    public Icons getIcons() {
        if (mCustomIcons == null) {
            mCustomIcons = new Icons();
        }
        return mCustomIcons;
    }

    public void setIcons(Icons icons) {
        this.mCustomIcons = icons;
    }

    /**
     * Extract the node id from virtual device id.
     * Example: ZWayVDev_13-0-49-5 - node id: 13
     *
     * @return node id
     */
    public Integer getNodeId() {
        // Check if virtual device comes with an associated device
        // ZWayVDev_[Node ID]-[Instance ID]-[Command Class ID]-[Scale ID] (see Z-Way Developers Documentation)
        // Example device id: ZWayVDev_13-0-49-5

        String regex = "(.*)_(\\d+)-(\\d)+-(\\d+)(.*)";

        if (getDeviceId().matches(regex)) {
            logger.debug("Device comes with an associated device.");

            Pattern pattern = Pattern.compile(regex);
            Matcher matcher = pattern.matcher(getDeviceId());
            if (matcher.matches()) {
                try {
                    return Integer.parseInt(matcher.group(2));
                } catch (NumberFormatException e) {
                    logger.warn("Couldn't match a node id (NumberFormatException).");
                }
            } else {
                logger.warn("Couldn't match a node id.");
            }
        } else {
            logger.debug("Device is only a virtual device.");
        }

        return -1;
    }

    public List<String> getTags() {
        return this.mTags;
    }

    public void setTags(List<String> tags) {
        this.mTags = tags;
    }

    /**
     * Set a Z-Way command handler.
     *
     * @param commandHandler
     */
    public void setCommandHandler(IDeviceCommands commandHandler) {
        mCommandHandler = commandHandler;
    }

    // available commands ...
    public String on() {
        throw new UnsupportedOperationException("Operation not supported by device type " + mDeviceType);
    }

    public String off() {
        throw new UnsupportedOperationException("Operation not supported by device type " + mDeviceType);
    }

    public String update() {
        throw new UnsupportedOperationException("Operation not supported by device type " + mDeviceType);
    }

    public String min() {
        throw new UnsupportedOperationException("Operation not supported by device type " + mDeviceType);
    }

    public String max() {
        throw new UnsupportedOperationException("Operation not supported by device type " + mDeviceType);
    }

    public String exact(String level) {
        throw new UnsupportedOperationException("Operation not supported by device type " + mDeviceType);
    }

    public String exactSmooth(String level, Integer duration) {
        throw new UnsupportedOperationException("Operation not supported by device type " + mDeviceType);
    }

    public String exact(Integer red, Integer green, Integer blue) {
        throw new UnsupportedOperationException("Operation not supported by device type " + mDeviceType);
    }

    public String up() {
        throw new UnsupportedOperationException("Operation not supported by device type " + mDeviceType);
    }

    public String down() {
        throw new UnsupportedOperationException("Operation not supported by device type " + mDeviceType);
    }

    public String upMax() {
        throw new UnsupportedOperationException("Operation not supported by device type " + mDeviceType);
    }

    public String startUp() {
        throw new UnsupportedOperationException("Operation not supported by device type " + mDeviceType);
    }

    public String startDown() {
        throw new UnsupportedOperationException("Operation not supported by device type " + mDeviceType);
    }

    public String stop() {
        throw new UnsupportedOperationException("Operation not supported by device type " + mDeviceType);
    }

    public String open() {
        throw new UnsupportedOperationException("Operation not supported by device type " + mDeviceType);
    }

    public String close() {
        throw new UnsupportedOperationException("Operation not supported by device type " + mDeviceType);
    }

    public String increase() {
        throw new UnsupportedOperationException("Operation not supported by device type " + mDeviceType);
    }

    public String decrease() {
        throw new UnsupportedOperationException("Operation not supported by device type " + mDeviceType);
    }

    public String upstart() {
        throw new UnsupportedOperationException("Operation not supported by device type " + mDeviceType);
    }

    public String upstop() {
        throw new UnsupportedOperationException("Operation not supported by device type " + mDeviceType);
    }

    public String downstart() {
        throw new UnsupportedOperationException("Operation not supported by device type " + mDeviceType);
    }

    public String downstop() {
        throw new UnsupportedOperationException("Operation not supported by device type " + mDeviceType);
    }

    // Camera (up, down, open, close already defined)

    public String zoomIn() {
        throw new UnsupportedOperationException("Operation not supported by device type " + mDeviceType);
    }

    public String zoomOut() {
        throw new UnsupportedOperationException("Operation not supported by device type " + mDeviceType);
    }

    public String left() {
        throw new UnsupportedOperationException("Operation not supported by device type " + mDeviceType);
    }

    public String right() {
        throw new UnsupportedOperationException("Operation not supported by device type " + mDeviceType);
    }

    /*
     * (non-Javadoc)
     *
     * @see java.lang.Object#toString()
     */
    @Override
    public String toString() {
        return new ToStringBuilder(this).append("creationTime", mCreationTime).append("creatorId", mCreatorId)
                .append("deviceType", mDeviceType).append("h", mH).append("hasHistory", mHasHistory)
                .append("deviceId", mDeviceId).append("location", mLocation)
                .append("permanentlyHidden", mPermanentlyHidden).append("probeType", mProbeType)
                .append("visibility", mVisibility).append("updateTime", mUpdateTime).append("metrics", mMetrics)
                .append("tags", mTags).append("customIcons", mCustomIcons).toString();
    }
} public class DeviceCommand {
    private String mDeviceId;
    private String mCommand;
    private Map<String, String> mParams;

    /**
     * Instantiate a command.
     *
     * @param deviceId ZAutomation device id
     * @param command ZAutamation command name
     * @param params parameter map
     */
    public DeviceCommand(String deviceId, String command, Map<String, String> params) {
        setDeviceId(deviceId);
        setCommand(command);
        mParams = params;
    }

    /**
     * Instantiate a command without parameter.
     *
     * @param deviceId ZAutomation device id
     * @param command ZAutamation command name
     */
    public DeviceCommand(String deviceId, String command) {
        setDeviceId(deviceId);
        setCommand(command);
        mParams = null;
    }

    public String getDeviceId() {
        return mDeviceId;
    }

    public void setDeviceId(String deviceId) {
        if (deviceId == null || deviceId.isEmpty()) {
            throw new IllegalArgumentException("device id is required");
        }

        mDeviceId = deviceId;
    }

    public String getCommand() {
        return mCommand;
    }

    public void setCommand(String command) {
        if (command == null || command.isEmpty()) {
            throw new IllegalArgumentException("command is required");
        }

        mCommand = command;
    }

    public Map<String, String> getParams() {
        return mParams;
    }

    public void setParams(Map<String, String> params) {
        mParams = params;
    }

    /*
     * (non-Javadoc)
     *
     * @see java.lang.Object#toString()
     */
    @Override
    public String toString() {
        ToStringBuilder toStringBuilder = new ToStringBuilder(this);
        if (mParams != null) {
            for (Entry<String, String> entry : mParams.entrySet()) {
                toStringBuilder.append(entry.getKey(), entry.getValue());
            }
        }

        return new ToStringBuilder(this).append("deviceId", mDeviceId).append("command", mCommand)
                .append("params", toStringBuilder.toString()).toString();
    }
} public class DeviceList {
    private List<Device> mDevices;

    public DeviceList() {
        mDevices = new ArrayList<Device>();
    }

    public void addDevice(Device device) {
        mDevices.add(device);
    }

    /**
     * @return list of virtual devices
     */
    public List<Device> getDevices() {
        ArrayList<Device> virtualDevices = new ArrayList<Device>();

        for (Device device : mDevices) {
            Integer nodeId = device.getNodeId();
            if (nodeId == -1) {
                virtualDevices.add(device);
            }
        }

        return virtualDevices;
    }

    public List<Device> getAllDevices() {
        return mDevices;
    }

    /**
     * Return the first occurrence of device
     *
     * @param deviceId ZAutomation device id
     * @return virtual device
     */
    public Device getDeviceById(String deviceId) {

        for (Device device : mDevices) {
            if (device.getDeviceId().equals(deviceId)) {
                return device;
            }
        }
        return null;
    }

    /**
     * @return list of physical devices with associated virtual devices
     */
    public Map<Integer, List<Device>> getDevicesGroupByNodeId() {
        Map<Integer, List<Device>> physicalDevices = new HashMap<Integer, List<Device>>();

        for (Device device : mDevices) {
            Integer nodeId = device.getNodeId();
            if (nodeId != -1) {
                if (physicalDevices.containsKey(nodeId)) {
                    physicalDevices.get(nodeId).add(device);
                } else {
                    ArrayList<Device> devices = new ArrayList<Device>();
                    devices.add(device);

                    physicalDevices.put(nodeId, devices);
                }
            }
        }

        return physicalDevices;
    }

    /**
     * @param nodeId Z-Wave device node id
     * @return list of physical devices with associated virtual devices
     */
    public Map<Integer, List<Device>> getDevicesByNodeId(Integer nodeId) {
        Map<Integer, List<Device>> physicalDevice = new HashMap<Integer, List<Device>>();

        for (Device device : mDevices) {
            if (nodeId == device.getNodeId()) {
                if (physicalDevice.containsKey(nodeId)) {
                    physicalDevice.get(nodeId).add(device);
                } else {
                    ArrayList<Device> devices = new ArrayList<Device>();
                    devices.add(device);

                    physicalDevice.put(nodeId, devices);
                }
            }
        }

        return physicalDevice;
    }

    /*
     * (non-Javadoc)
     *
     * @see java.lang.Object#toString()
     */
    @Override
    public String toString() {
        ToStringBuilder toStringBuilder = new ToStringBuilder(this);
        for (Device device : mDevices) {
            toStringBuilder.append(device);
        }

        return new ToStringBuilder(this).append("deviceList", toStringBuilder.toString()).toString();
    }
} public class IconList {
    private List<Icon> mIcons;

    /**
     * Instantiate a icon list with default values.
     */
    public IconList() {
        mIcons = new ArrayList<Icon>();
    }

    public void addIcon(Icon icon) {
        mIcons.add(icon);
    }

    public List<Icon> getIcons() {
        return mIcons;
    }

    /*
     * (non-Javadoc)
     *
     * @see java.lang.Object#toString()
     */
    @Override
    public String toString() {
        ToStringBuilder toStringBuilder = new ToStringBuilder(this);
        for (Icon icon : mIcons) {
            toStringBuilder.append(icon);
        }

        return new ToStringBuilder(this).append("iconList", toStringBuilder.toString()).toString();
    }
} public abstract class Instance {
    @SerializedName("instanceId")
    private String mInstanceId;
    @SerializedName("moduleId")
    private String mModuleId;
    @SerializedName("active")
    private Boolean mActive;
    @SerializedName("title")
    private String mTitle;
    @SerializedName("id")
    private Integer mId;
    @SerializedName("creationTime")
    private Long mCreationTime;

    /**
     * Instantiate a instance with default values.
     */
    public Instance() {
        mInstanceId = "";
        mModuleId = "";
        mActive = true;
        mTitle = "";
        mId = -1;
        mCreationTime = new Date().getTime() / 1000;
    }

    public String getInstanceId() {
        if (mInstanceId == null) {
            mInstanceId = "";
        }
        return mInstanceId;
    }

    public void setInstanceId(String instanceId) {
        this.mInstanceId = instanceId;
    }

    public String getModuleId() {
        if (mModuleId == null) {
            mModuleId = "";
        }
        return mModuleId;
    }

    public void setModuleId(String moduleId) {
        this.mModuleId = moduleId;
    }

    public Boolean getActive() {
        if (mActive == null) {
            mActive = true;
        }
        return mActive;
    }

    public void setActive(Boolean active) {
        this.mActive = active;
    }

    public String getTitle() {
        if (mTitle == null) {
            mTitle = "";
        }
        return mTitle;
    }

    public void setTitle(String title) {
        this.mTitle = title;
    }

    public Integer getId() {
        if (mId == null) {
            mId = -1;
        }
        return mId;
    }

    public void setId(Integer id) {
        this.mId = id;
    }

    public Long getCreationTime() {
        if (mCreationTime == null) {
            mCreationTime = -1l;
        }
        return mCreationTime;
    }

    public void setCreationTime(Long creationTime) {
        this.mCreationTime = creationTime;
    }

    /*
     * (non-Javadoc)
     *
     * @see java.lang.Object#toString()
     */
    @Override
    public String toString() {
        return new ToStringBuilder(this).append("instanceId", mInstanceId).append("moduleId", mModuleId)
                .append("active", mActive).append("title", mTitle).append("id", mId)
                .append("creationTime", mCreationTime).toString();
    }
} public class InstanceList {
    private List<Instance> mInstances;

    /**
     * Instantiate a instance list with default values.
     */
    public InstanceList() {
        mInstances = new ArrayList<Instance>();
    }

    public void addInstance(Instance instance) {
        mInstances.add(instance);
    }

    public List<Instance> getInstances() {
        return mInstances;
    }

    /**
     * Return the first occurrence of instance
     *
     * @param moduleId ZAutomation module id
     * @return instance or null if not found
     */
    public Instance getInstanceByModuleId(String moduleId) {
        for (Instance instance : mInstances) {
            if (instance.getModuleId().equals(moduleId)) {
                return instance;
            }
        }
        return null;
    }

    /*
     * (non-Javadoc)
     *
     * @see java.lang.Object#toString()
     */
    @Override
    public String toString() {
        ToStringBuilder toStringBuilder = new ToStringBuilder(this);
        for (Instance instance : mInstances) {
            toStringBuilder.append(instance);
        }

        return new ToStringBuilder(this).append("instanceList", toStringBuilder.toString()).toString();
    }
} public class Location {
    @SerializedName("id")
    private Integer mId;
    @SerializedName("title")
    private String mTitle;
    @SerializedName("user_img")
    private String mUserImg;

    /**
     * Instantiate a location with default values.
     */
    public Location() {
        mId = -1;
        mTitle = "";
        mUserImg = "";
    }

    public Integer getId() {
        if (mId == null) {
            mId = -1;
        }
        return mId;
    }

    public void setId(Integer id) {
        this.mId = id;
    }

    public String getTitle() {
        if (mTitle == null) {
            mTitle = "";
        }
        return mTitle;
    }

    public void setTitle(String title) {
        this.mTitle = title;
    }

    public String getUserImg() {
        if (mUserImg == null) {
            mUserImg = "";
        }
        return mUserImg;
    }

    public void setUserImg(String userImg) {
        this.mUserImg = userImg;
    }

    /*
     * (non-Javadoc)
     *
     * @see java.lang.Object#toString()
     */
    @Override
    public String toString() {
        return new ToStringBuilder(this).append("id", mId).append("title", mTitle).append("userImg", mUserImg)
                .toString();
    }
} public class LocationList {
    private List<Location> mLocations;

    /**
     * Instantiate a location list with default values.
     */
    public LocationList() {
        mLocations = new ArrayList<Location>();
    }

    public void addLocation(Location location) {
        mLocations.add(location);
    }

    public List<Location> getLocations() {
        return mLocations;
    }

    /**
     * Return the first occurrence of location
     *
     * @param id ZAutomation location id
     * @return location or null if not found
     */
    public Location getLocationById(Integer id) {
        for (Location location : mLocations) {
            if (location.getId().equals(id)) {
                return location;
            }
        }
        return null;
    }

    /*
     * (non-Javadoc)
     *
     * @see java.lang.Object#toString()
     */
    @Override
    public String toString() {
        ToStringBuilder toStringBuilder = new ToStringBuilder(this);
        for (Location location : mLocations) {
            toStringBuilder.append(location);
        }

        return new ToStringBuilder(this).append("locationList", toStringBuilder.toString()).toString();
    }
} public class ModuleList {
    // TODO
} public class NamespaceList {
    // TODO
} public class Notification {
    @SerializedName("id")
    private Long mId;
    @SerializedName("timestamp")
    private Date mTimestamp;
    @SerializedName("level")
    private String mLevel;
    @SerializedName("message")
    private Message mMessage;
    @SerializedName("type")
    private String mType;
    @SerializedName("source")
    private String mSource;

    /**
     * Instantiate a notification with default values.
     */
    public Notification() {
        mId = -1l;
        mTimestamp = new Date();
        mLevel = "";
        mMessage = new Message();
        mType = "";
        mSource = "";
    }

    public Long getId() {
        if (mId == null) {
            mId = -1l;
        }
        return mId;
    }

    public void setId(Long id) {
        this.mId = id;
    }

    public Date getTimestamp() {
        if (mTimestamp == null) {
            mTimestamp = new Date();
        }
        return mTimestamp;
    }

    public void setTimestamp(Date timestamp) {
        this.mTimestamp = timestamp;
    }

    public String getLevel() {
        if (mLevel == null) {
            mLevel = "";
        }
        return mLevel;
    }

    public void setLevel(String level) {
        this.mLevel = level;
    }

    public Message getMessage() {
        if (mMessage == null) {
            mMessage = new Message();
        }
        return mMessage;
    }

    public void setMessage(Message message) {
        this.mMessage = message;
    }

    public String getType() {
        if (mType == null) {
            mType = "";
        }
        return mType;
    }

    public void setType(String type) {
        this.mType = type;
    }

    public String getSource() {
        if (mSource == null) {
            mSource = "";
        }
        return mSource;
    }

    public void setSource(String source) {
        this.mSource = source;
    }

    /*
     * (non-Javadoc)
     *
     * @see java.lang.Object#toString()
     */
    @Override
    public String toString() {
        return new ToStringBuilder(this).append("id", mId).append("timestamp", mTimestamp).append("level", mLevel)
                .append("message", mMessage).append("type", mType).append("source", mSource).toString();
    }
} public class NotificationList {
    private List<Notification> mNotifications;

    /**
     * Instantiate a instance list with default values.
     */
    public NotificationList() {
        mNotifications = new ArrayList<Notification>();
    }

    public void addNotification(Notification notification) {
        mNotifications.add(notification);
    }

    public List<Notification> getNotifications() {
        return mNotifications;
    }

    /**
     * /*
     * (non-Javadoc)
     *
     * @see java.lang.Object#toString()
     */
    @Override
    public String toString() {
        ToStringBuilder toStringBuilder = new ToStringBuilder(this);
        for (Notification notification : mNotifications) {
            toStringBuilder.append(notification);
        }

        return new ToStringBuilder(this).append("notificationList", toStringBuilder.toString()).toString();
    }
} public class Profile {
    @SerializedName("id")
    private Integer mId;
    @SerializedName("name")
    private String mName;
    @SerializedName("lang")
    private String mLang;
    @SerializedName("color")
    private String mColor;
    @SerializedName("dashboard")
    private Set<String> mDashboard;
    @SerializedName("interval")
    private Integer mInterval;
    @SerializedName("rooms")
    private Set<Integer> mRooms;
    @SerializedName("expert_view")
    private Boolean mExpertView;
    @SerializedName("hide_all_device_events")
    private Boolean mHideAllDeviceEvents;
    @SerializedName("hide_system_events")
    private Boolean mHideSystemEvents;
    @SerializedName("hide_single_device_events")
    private Set<String> mHideSingleDeviceEvents;
    @SerializedName("email")
    private String mEmail;

    /**
     * Instantiate a profile with default values.
     */
    public Profile() {
        mId = -1;
        mName = "";
        mLang = "";
        mColor = "";
        mDashboard = new HashSet<>();
        mInterval = -1;
        mRooms = new HashSet<>();
        mExpertView = false;
        mHideAllDeviceEvents = false;
        mHideSystemEvents = false;
        mHideSingleDeviceEvents = new HashSet<>();
        mEmail = "";
    }

    public Integer getId() {
        if (mId == null) {
            mId = -1;
        }
        return mId;
    }

    public void setId(Integer id) {
        this.mId = id;
    }

    public String getName() {
        if (mName == null) {
            mName = "";
        }
        return mName;
    }

    public void setName(String name) {
        this.mName = name;
    }

    public String getLang() {
        if (mLang == null) {
            mLang = "";
        }
        return mLang;
    }

    public void setLang(String lang) {
        this.mLang = lang;
    }

    public String getColor() {
        if (mColor == null) {
            mColor = "";
        }
        return mColor;
    }

    public void setColor(String color) {
        this.mColor = color;
    }

    public Set<String> getDashboard() {
        if (mDashboard == null) {
            mDashboard = new HashSet<>();
        }
        return mDashboard;
    }

    public void setDashboard(Set<String> dashboard) {
        this.mDashboard = dashboard;
    }

    public Integer getInterval() {
        if (mInterval == null) {
            mInterval = -1;
        }
        return mInterval;
    }

    public void setInterval(Integer interval) {
        this.mInterval = interval;
    }

    public Set<Integer> getRooms() {
        if (mRooms == null) {
            mRooms = new HashSet<>();
        }
        return mRooms;
    }

    public void setRooms(Set<Integer> rooms) {
        this.mRooms = rooms;
    }

    public Boolean getExpertView() {
        if (mExpertView == null) {
            mExpertView = false;
        }
        return mExpertView;
    }

    public void setExpertView(Boolean expertView) {
        this.mExpertView = expertView;
    }

    public Boolean getHideAllDeviceEvents() {
        if (mHideAllDeviceEvents == null) {
            mHideAllDeviceEvents = false;
        }
        return mHideAllDeviceEvents;
    }

    public void setHideAllDeviceEvents(Boolean hideAllDeviceEvents) {
        this.mHideAllDeviceEvents = hideAllDeviceEvents;
    }

    public Boolean getHideSystemEvents() {
        if (mHideSystemEvents == null) {
            mHideSystemEvents = false;
        }
        return mHideSystemEvents;
    }

    public void setHideSystemEvents(Boolean hideSystemEvents) {
        this.mHideSystemEvents = hideSystemEvents;
    }

    public Set<String> getHideSingleDeviceEvents() {
        if (mHideSingleDeviceEvents == null) {
            mHideSingleDeviceEvents = new HashSet<>();
        }
        return mHideSingleDeviceEvents;
    }

    public void setHideSingleDeviceEvents(Set<String> hideSingleDeviceEvents) {
        this.mHideSingleDeviceEvents = hideSingleDeviceEvents;
    }

    public String getEmail() {
        if (mEmail == null) {
            mEmail = "";
        }
        return mEmail;
    }

    public void setEmail(String email) {
        this.mEmail = email;
    }

    /*
     * (non-Javadoc)
     *
     * @see java.lang.Object#toString()
     */
    @Override
    public String toString() {
        return new ToStringBuilder(this).append("id", mId).append("name", mName).append("lang", mLang)
                .append("color", mColor).append("dashboard", mDashboard).append("interval", mInterval)
                .append("rooms", mRooms).append("expertView", mExpertView)
                .append("hideAllDeviceEvents", mHideAllDeviceEvents).append("hideSystemEvents", mHideSystemEvents)
                .append("hideSingleDeviceEvents", mHideSingleDeviceEvents).append("email", mEmail).toString();
    }
} public class ProfileList {
    private List<Profile> mProfiles;

    /**
     * Instantiate a instance list with default values.
     */
    public ProfileList() {
        mProfiles = new ArrayList<Profile>();
    }

    public void addProfile(Profile profile) {
        mProfiles.add(profile);
    }

    public List<Profile> getProfiles() {
        return mProfiles;
    }

    /**
     * /*
     * (non-Javadoc)
     *
     * @see java.lang.Object#toString()
     */
    @Override
    public String toString() {
        ToStringBuilder toStringBuilder = new ToStringBuilder(this);
        for (Profile profile : mProfiles) {
            toStringBuilder.append(profile);
        }

        return new ToStringBuilder(this).append("profileList", toStringBuilder.toString()).toString();
    }
} public class SystemInfo {
    @SerializedName("first_start_up")
    private Date mFirstStartUp;
    @SerializedName("count_of_reconnects")
    private Integer mCountOfReconnects;
    @SerializedName("current_firmware")
    private String mCurrentFirmware;
    @SerializedName("current_firmware_majurity")
    private String mCurrentFirmwareMajurity;

    /**
     * Instantiate a system info element object with default values.
     */

    public SystemInfo() {
        mFirstStartUp = new Date();
        mCountOfReconnects = -1;
        mCurrentFirmware = "";
        mCurrentFirmwareMajurity = "";
    }

    public Date getFirstStartUp() {
        if (mFirstStartUp == null) {
            mFirstStartUp = new Date();
        }
        return mFirstStartUp;
    }

    public void setFirstStartUp(Date firstStartUp) {
        this.mFirstStartUp = firstStartUp;
    }

    public Integer getCountOfReconnects() {
        if (mCountOfReconnects == null) {
            mCountOfReconnects = -1;
        }
        return mCountOfReconnects;
    }

    public void setCountOfReconnects(Integer countOfReconnects) {
        this.mCountOfReconnects = countOfReconnects;
    }

    public String getCurrentFirmware() {
        if (mCurrentFirmware == null) {
            mCurrentFirmware = "";
        }
        return mCurrentFirmware;
    }

    public void setCurrentFirmware(String currentFirmware) {
        this.mCurrentFirmware = currentFirmware;
    }

    public String getCurrentFirmwareMajurity() {
        if (mCurrentFirmwareMajurity == null) {
            mCurrentFirmwareMajurity = "";
        }
        return mCurrentFirmwareMajurity;
    }

    public void setCurrentFirmwareMajurity(String currentFirmwareMajurity) {
        this.mCurrentFirmwareMajurity = currentFirmwareMajurity;
    }

    /*
     * (non-Javadoc)
     *
     * @see java.lang.Object#toString()
     */
    @Override
    public String toString() {
        return new ToStringBuilder(this).append("first_start_up", mFirstStartUp)
                .append("count_of_reconnects", mCountOfReconnects).append("current_firmware", mCurrentFirmware)
                .append("current_firmware_majurity", mCurrentFirmwareMajurity).toString();
    }
} public class ZWaveController {
    @SerializedName("data")
    private ZWaveControllerData mData;

    /**
     * Instantiate a Z-Wave device object with default values.
     */
    public ZWaveController() {
        mData = new ZWaveControllerData();
    }

    public ZWaveControllerData getData() {
        if (mData == null) {
            mData = new ZWaveControllerData();
        }
        return mData;
    }

    public void setData(ZWaveControllerData data) {
        this.mData = data;
    }

    /*
     * (non-Javadoc)
     *
     * @see java.lang.Object#toString()
     */
    @Override
    public String toString() {
        return new ToStringBuilder(this).append("data", mData).toString();
    }
} public class ZWaveDevice {
    @SerializedName("instances")
    private ZWaveDeviceInstances mInstances;
    @SerializedName("data")
    private ZWaveDeviceData mData;
    @SerializedName("id")
    private Integer mId;

    /**
     * Instantiate a Z-Wave device object with default values.
     */
    public ZWaveDevice() {
        mInstances = new ZWaveDeviceInstances();
        mData = new ZWaveDeviceData();
        mId = -1;
    }

    public ZWaveDeviceInstances getInstances() {
        if (mInstances == null) {
            mInstances = new ZWaveDeviceInstances();
        }
        return mInstances;
    }

    public void setInstances(ZWaveDeviceInstances instances) {
        this.mInstances = instances;
    }

    public ZWaveDeviceData getData() {
        if (mData == null) {
            mData = new ZWaveDeviceData();
        }
        return mData;
    }

    public void setData(ZWaveDeviceData data) {
        this.mData = data;
    }

    public Integer getId() {
        if (mId == null) {
            mId = -1;
        }
        return mId;
    }

    public void setId(Integer id) {
        this.mId = id;
    }

    /*
     * (non-Javadoc)
     *
     * @see java.lang.Object#toString()
     */
    @Override
    public String toString() {
        return new ToStringBuilder(this).append("instances", mInstances).append("data", mData).append("id", mId)
                .toString();
    }
}
import java.io.File;
import java.util.ArrayList;
import java.util.Date;
import de.fh_zwickau.informatik.sensor.model.devicehistory.DeviceHistoryData;
import de.fh_zwickau.informatik.sensor.model.devicehistory.DeviceHistoryList;
import de.fh_zwickau.informatik.sensor.model.devices.Device;
import de.fh_zwickau.informatik.sensor.model.devices.DeviceCommand;
import de.fh_zwickau.informatik.sensor.model.devices.DeviceList;
import de.fh_zwickau.informatik.sensor.model.icons.IconList;
import de.fh_zwickau.informatik.sensor.model.instances.Instance;
import de.fh_zwickau.informatik.sensor.model.instances.InstanceList;
import de.fh_zwickau.informatik.sensor.model.locations.Location;
import de.fh_zwickau.informatik.sensor.model.locations.LocationList;
import de.fh_zwickau.informatik.sensor.model.modules.ModuleList;
import de.fh_zwickau.informatik.sensor.model.namespaces.NamespaceList;
import de.fh_zwickau.informatik.sensor.model.notifications.Notification;
import de.fh_zwickau.informatik.sensor.model.notifications.NotificationList;
import de.fh_zwickau.informatik.sensor.model.profiles.Profile;
import de.fh_zwickau.informatik.sensor.model.profiles.ProfileList;
import de.fh_zwickau.informatik.sensor.model.system.SystemInfo;
import de.fh_zwickau.informatik.sensor.model.zwaveapi.controller.ZWaveController;
import de.fh_zwickau.informatik.sensor.model.zwaveapi.devices.ZWaveDevice;
/**
 * Copyright (C) 2016 by Software-Systementwicklung Zwickau Research Group
 *
 * 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 de.fh_zwickau.informatik.sensor;



/**
 * The {@link IZWayApi} represents the ZAutomation API (and ZWaveAPI). See also:
 * http://docs.zwayhomeautomation.apiary.io/#
 *
 * @author Patrick Hecker - Initial contribution
 */
public interface IZWayApi {
    static String VERSION = "/v1";
    static String PATH = "/ZAutomation/api";
    static String ZWAVE_PATH = "/ZWaveAPI/Run";

    // Platform Availability
    /**
     * @return Z-Way server status
     */
    String getStatus();

    /**
     * Asynchronous version of {@link #getStatus()}
     *
     * @param callback contains the same data like synchronous return value
     */
    void getStatus(IZWayCallback<String> callback);

    // Platform Restart
    /**
     * @return true if successfully performed
     */
    Boolean getRestart();

    /**
     * Asynchronous version of {@link #getRestart()}
     *
     * @param callback contains the same data like synchronous return value
     */
    void getRestart(IZWayCallback<Boolean> callback);

    // Login
    /**
     * @return Z-Way session id
     */
    String getLogin();

    // no asynchronous version for login call

    // Current profile
    /**
     * @return ZAutomation profile
     */
    Profile getCurrentProfile();

    // Namespaces
    /**
     * @return ZAutomation namespace list
     */
    NamespaceList getNamespaces();

    /**
     * Asynchronous version of {@link #getNamespaces()}
     *
     * @param callback contains the same data like synchronous return value
     */
    void getNamespaces(IZWayCallback<NamespaceList> callback);

    // Instances and Modules
    /**
     * @return ZAutomation module list
     */
    ModuleList getModules();

    /**
     * Asynchronous version of {@link #getModules()}
     *
     * @param callback contains the same data like synchronous return value
     */
    void getModules(IZWayCallback<ModuleList> callback);

    /**
     * @return ZAutomation instance list
     */
    InstanceList getInstances();

    /**
     * Asynchronous version of {@link #getInstances()}
     *
     * @param callback contains the same data like synchronous return value
     */
    void getInstances(IZWayCallback<InstanceList> callback);

    /**
     * @param instance ZAutomation instance
     * @return new ZAutomation instance
     */
    Instance postInstance(Instance instance);

    /**
     * Asynchronous version of {@link #postInstance(Instance)}
     *
     * @param instance ZAutomation instance
     * @param callback contains the same data like synchronous return value
     */
    void postInstance(Instance instance, IZWayCallback<Instance> callback);

    /**
     * @param instanceId ZAutomation instance id
     * @return ZAutomation instance
     */
    Instance getInstance(Integer instanceId);

    /**
     * Asynchronous version of {@link #getInstance(String)}
     *
     * @param instanceId ZAutomation instance id
     * @param callback contains the same data like synchronous return value
     */
    void getInstance(Integer instanceId, IZWayCallback<Instance> callback);

    /**
     * @param instance ZAutomation instance
     * @return updated ZAutomation instance
     */
    Instance putInstance(Instance instance);

    /**
     * Asynchronous version of {@link #putInstance(Instance)}
     *
     * @param instance ZAutomation instance
     * @param callback contains the same data like synchronous return value
     */
    void putInstance(Instance instance, IZWayCallback<Instance> callback);

    /**
     * @param instanceId ZAutomation instance id
     * @return true if ZAutomation instance deleted
     */
    Boolean deleteInstance(Integer instanceId);

    /**
     * Asynchronous version of {@link #deleteInstance(String)}
     *
     * @param instanceId ZAutomation instance id
     * @param callback contains the same data like synchronous return value
     */
    void deleteInstance(Integer instanceId, IZWayCallback<Boolean> callback);

    // Devices

    /**
     * @return ZAutomation device list
     */
    DeviceList getDevices();

    /**
     * Asynchronous version of {@link #getDevices()}
     *
     * @param callback contains the same data like synchronous return value
     */
    void getDevices(IZWayCallback<DeviceList> callback);

    /**
     * @param device ZAutomation device
     * @return new ZAutomation device
     */
    Device putDevice(Device device);

    /**
     * Asynchronous version of {@link #postDevice(Device)}
     *
     * @param device ZAutomation device
     * @param callback contains the same data like synchronous return value
     */
    void putDevice(Device device, IZWayCallback<Device> callback);

    /**
     * @param deviceId ZAutomation device id
     * @return ZAutomation device
     */
    Device getDevice(String deviceId);

    /**
     * Asynchronous version of {@link #getDevice(String)}
     *
     * @param deviceId ZAutomation device id
     * @param callback contains the same data like synchronous return value
     */
    void getDevice(String deviceId, IZWayCallback<Device> callback);

    /**
     * Use this method to get the complete JSON string of a device.
     * This is useful for special devices, such as the weather app.
     * In this case, the client must parse and interpret the data structure.
     *
     * @param deviceId ZAutomation device id
     * @return JSON string
     */
    String getDeviceAsJson(String deviceId);

    /**
     * Asynchronous version of {@link #getDeviceAsJson(String)}
     *
     * @param deviceId ZAutomation device id
     * @param callback contains the same data like synchronous return value
     */
    void getDeviceAsJson(String deviceId, IZWayCallback<String> callback);

    /**
     * @param command ZAutomation command
     * @return response message
     */
    String getDeviceCommand(DeviceCommand command);

    /**
     * Asynchronous version of {@link #getDeviceCommand(DeviceCommand)}
     *
     * @param command ZAutomation command
     * @param callback contains the same data like synchronous return value
     */
    void getDeviceCommand(DeviceCommand command, IZWayCallback<String> callback);

    // Locations

    /**
     * @return ZAutomation location list
     */
    LocationList getLocations();

    /**
     * Asynchronous version of {@link #getLocations()}
     *
     * @param callback contains the same data like synchronous return value
     */
    void getLocations(IZWayCallback<LocationList> callback);

    /**
     * @param location ZAutomation location id
     * @return new ZAutomation location id
     */
    Location postLocation(Location location);

    /**
     * Asynchronous version of {@link #postLocation(Location)}
     *
     * @param location ZAutomation location
     * @param callback contains the same data like synchronous return value
     */
    void postLocation(Location location, IZWayCallback<Location> callback);

    /**
     * @param locationId ZAutomation location id
     * @return ZAutomation location
     */
    Location getLocation(String locationId);

    /**
     * Asynchronous version of {@link #getLocation(String)}
     *
     * @param locationId ZAutomation location id
     * @param callback contains the same data like synchronous return value
     */
    void getLocation(String locationId, IZWayCallback<Location> callback);

    /**
     * @param location ZAutomation location
     * @return updated ZAutomation location
     */
    Location putLocation(Location location);

    /**
     * Asynchronous version of {@link #putLocation(Location)}
     *
     * @param location ZAutomation location
     * @param callback contains the same data like synchronous return value
     */
    void putLocation(Location location, IZWayCallback<Location> callback);

    /**
     * @param locationId ZAutomation location id
     * @return true if ZAutomation location deleted
     */
    Boolean deleteLocation(String locationId);

    /**
     * Asynchronous version of {@link #deleteLocation(String)}
     *
     * @param locationId ZAutomation location id
     * @param callback contains the same data like synchronous return value
     */
    void deleteLocation(String locationId, IZWayCallback<Boolean> callback);

    // Profiles

    /**
     * @return ZAutomation profile list
     */
    ProfileList getProfiles();