diff --git a/dserial-protocol/controller.xml b/dserial-protocol/controller.xml
index 6399856e9c80e9c1e7ce42a394e06da54441312a..6d453865a04ef4e1bc17a8c811f49622e7b71ad9 100644
--- a/dserial-protocol/controller.xml
+++ b/dserial-protocol/controller.xml
@@ -19,11 +19,17 @@ Rest of DSerial project is NOT released under CC0
 
 		List of ports.
 
-		Change signal is only emitted upon interaction with server.
-		Server does not actively check for port changes.
+		Server checks for changes every second.
 		-->
 		<property name='PortList' type='as' access='read'/>
 
+		<!--
+		ServerVersion:
+
+		Prints version of server
+		-->
+		<property name='ServerVersion' type='s' access='read'/>
+
 		<!--
 		CreateFakePort:
 
diff --git a/dserial-server/controller.cpp b/dserial-server/controller.cpp
index cb9cf6aa2f714a049c701cbcec725eea65ee2817..f2cc520ddc0032917aa6f5216552c5e0b9a5780c 100644
--- a/dserial-server/controller.cpp
+++ b/dserial-server/controller.cpp
@@ -90,16 +90,21 @@ void Controller::removePort(QDBusObjectPath id)
 	}
 }
 
+QString Controller::ServerVersion() const
+{
+	return "0.5";
+}
+
 void Controller::notifyPropertyChanged( const char *propertyName )
 {
-    QDBusMessage signal = QDBusMessage::createSignal(
-	"/controller",
-	"org.freedesktop.DBus.Properties",
-	"PropertiesChanged");
-    signal << QString("info.skorepa.DSerial.controller");
-    QVariantMap changedProps;
-    changedProps.insert(propertyName, property(propertyName));
-    signal << changedProps;
-    signal << QStringList();
-    QDBusConnection::sessionBus().send(signal);
+	QDBusMessage signal = QDBusMessage::createSignal(
+				      "/controller",
+				      "org.freedesktop.DBus.Properties",
+				      "PropertiesChanged");
+	signal << QString("info.skorepa.DSerial.controller");
+	QVariantMap changedProps;
+	changedProps.insert(propertyName, property(propertyName));
+	signal << changedProps;
+	signal << QStringList();
+	QDBusConnection::sessionBus().send(signal);
 }
diff --git a/dserial-server/controller.h b/dserial-server/controller.h
index c6148b8acaa65755c8389882603de748db9821c6..f6db700bdc254876bfbc9842f8998ef58c4c224a 100644
--- a/dserial-server/controller.h
+++ b/dserial-server/controller.h
@@ -9,33 +9,35 @@
 
 class Controller : public QObject
 {
-		Q_OBJECT
-		QVector<Port*> ports;
+	Q_OBJECT
+	QVector<Port*> ports;
 
-	public:
-		explicit Controller(QObject *parent = 0);
-		Q_PROPERTY(QStringList PortList READ PortList NOTIFY PortListChanged)
+    public:
+	explicit Controller(QObject *parent = 0);
+	Q_PROPERTY(QStringList PortList READ PortList NOTIFY PortListChanged)
+	Q_PROPERTY(QString ServerVersion READ ServerVersion)
 
-		QStringList PortList() const;
+	QStringList PortList() const;
 
-	public slots:
-		void CreateFakePort(QString);
-		void CreateFilePort(QString);
-		void Autodetect();
+    public slots:
+	void CreateFakePort(QString);
+	void CreateFilePort(QString);
+	void Autodetect();
 
-		QDBusObjectPath GetPath(QString name);
+	QDBusObjectPath GetPath(QString name);
 
-	signals:
-		void PortListChanged(QList<QDBusObjectPath> PortList);
+    signals:
+	void PortListChanged(QList<QDBusObjectPath> PortList);
 
-	private slots:
-		void removePort(QDBusObjectPath id);
+    private slots:
+	void removePort(QDBusObjectPath id);
 
-	public:
-		QDBusConnection connection;
+    public:
+	QDBusConnection connection;
+	QString ServerVersion() const;
 
-	private:
-		void notifyPropertyChanged( const char *propertyName );
+private:
+	void notifyPropertyChanged( const char *propertyName );
 };
 
 #endif // CONTROLLER_H
diff --git a/dserial-server/dserial-server.pro b/dserial-server/dserial-server.pro
index d7f4083bb6650916e2ff586e84dd71704a8615ff..3abaaa6ebc9082f428411488c148bb737811e229 100644
--- a/dserial-server/dserial-server.pro
+++ b/dserial-server/dserial-server.pro
@@ -19,11 +19,15 @@ DBUS_ADAPTORS += ../dserial-protocol/port.xml ../dserial-protocol/controller.xml
 
 SOURCES += main.cpp \
     port.cpp \
-    controller.cpp
+    controller.cpp \
+    udevmonitor.cpp
 
 HEADERS += \
     port.h \
-    controller.h
+    controller.h \
+    udevmonitor.h
+
+LIBS += -ludev
 
 documentation.path = .
 
diff --git a/dserial-server/main.cpp b/dserial-server/main.cpp
index 13fc5f42ceb0073481e20ea6ec4bbfb89606aba8..57b3b6a258367e7da25b06cf7498c726ec125c34 100644
--- a/dserial-server/main.cpp
+++ b/dserial-server/main.cpp
@@ -4,6 +4,7 @@
 #include <QLoggingCategory>
 #include "controller.h"
 #include "controller_adaptor.h"
+#include "udevmonitor.h"
 
 void msgHandler( QtMsgType type, const QMessageLogContext& context, const QString& msg )
 {
@@ -29,5 +30,14 @@ int main(int argc, char *argv[])
 	new ControllerAdaptor(controller);
 	controller->connection.registerObject("/controller", controller);
 	controller->connection.registerService("info.skorepa.DSerial1");
+	QTimer timer;
+	UdevMonitor mon;
+	QObject::connect(&timer, &QTimer::timeout,
+			 [&controller,&mon](){
+		if(mon.checkChange()) controller->Autodetect();
+	});
+	timer.setInterval(1000);
+	timer.start();
+
 	return a.exec();
 }
diff --git a/dserial-server/udevmonitor.cpp b/dserial-server/udevmonitor.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..2451b2b922841d00aa0d7b6c3a120b7312a365a2
--- /dev/null
+++ b/dserial-server/udevmonitor.cpp
@@ -0,0 +1,41 @@
+#include "udevmonitor.h"
+
+UdevMonitor::UdevMonitor(QObject *parent) : QObject(parent)
+{
+    udev = udev_new();
+    mon = udev_monitor_new_from_netlink(udev, "udev");
+    udev_monitor_filter_add_match_subsystem_devtype(mon, "usb-serial", NULL);
+    udev_monitor_enable_receiving(mon);
+
+    fd = udev_monitor_get_fd(mon);
+}
+
+UdevMonitor::~UdevMonitor()
+{
+    udev_unref(udev);
+    udev_monitor_unref(mon);
+}
+
+bool UdevMonitor::checkChange()
+{
+    fd_set fds;
+    struct timeval tv;
+    int ret;
+
+    FD_ZERO(&fds);
+    FD_SET(fd, &fds);
+    tv.tv_sec = 0;
+    tv.tv_usec = 0;
+
+    ret = select(fd+1, &fds, NULL, NULL, &tv);
+
+    /* Check if our file descriptor has received data. */
+    if (ret > 0 && FD_ISSET(fd, &fds)) {
+        struct udev_device *dev = udev_monitor_receive_device(mon);
+        udev_device_unref(dev);
+        emit changeDetected();
+        return true;
+    }
+    return false;
+}
+
diff --git a/dserial-server/udevmonitor.h b/dserial-server/udevmonitor.h
new file mode 100644
index 0000000000000000000000000000000000000000..94a5581054a65f203ad119a501c9d8afe6edad6f
--- /dev/null
+++ b/dserial-server/udevmonitor.h
@@ -0,0 +1,26 @@
+#ifndef UDEVMONITOR_H
+#define UDEVMONITOR_H
+
+#include <QObject>
+#include <libudev.h>
+
+class UdevMonitor : public QObject
+{
+    Q_OBJECT
+public:
+    explicit UdevMonitor(QObject *parent = 0);
+    ~UdevMonitor();
+
+signals:
+    void changeDetected();
+
+public slots:
+    bool checkChange();
+
+private:
+    struct udev *udev;
+    struct udev_monitor *mon;
+    int fd;
+};
+
+#endif // UDEVMONITOR_H