diff --git a/homeassistant/components/camera/synology.py b/homeassistant/components/camera/synology.py
index 90dfa58d8c54a5de35cf2cb6962d8c00972a8993..be01a7fc90d950d12f8916731778dd664fe65661 100644
--- a/homeassistant/components/camera/synology.py
+++ b/homeassistant/components/camera/synology.py
@@ -7,44 +7,25 @@ https://home-assistant.io/components/camera.synology/
 import asyncio
 import logging
 
+import requests
 import voluptuous as vol
 
-import aiohttp
-import async_timeout
-
 from homeassistant.const import (
     CONF_NAME, CONF_USERNAME, CONF_PASSWORD,
     CONF_URL, CONF_WHITELIST, CONF_VERIFY_SSL, CONF_TIMEOUT)
 from homeassistant.components.camera import (
     Camera, PLATFORM_SCHEMA)
 from homeassistant.helpers.aiohttp_client import (
-    async_get_clientsession, async_create_clientsession,
+    async_create_clientsession,
     async_aiohttp_proxy_web)
 import homeassistant.helpers.config_validation as cv
-from homeassistant.util.async import run_coroutine_threadsafe
+
+REQUIREMENTS = ['py-synology==0.1.1']
 
 _LOGGER = logging.getLogger(__name__)
 
 DEFAULT_NAME = 'Synology Camera'
-DEFAULT_STREAM_ID = '0'
 DEFAULT_TIMEOUT = 5
-CONF_CAMERA_NAME = 'camera_name'
-CONF_STREAM_ID = 'stream_id'
-
-QUERY_CGI = 'query.cgi'
-QUERY_API = 'SYNO.API.Info'
-AUTH_API = 'SYNO.API.Auth'
-CAMERA_API = 'SYNO.SurveillanceStation.Camera'
-STREAMING_API = 'SYNO.SurveillanceStation.VideoStream'
-SESSION_ID = '0'
-
-WEBAPI_PATH = '/webapi/'
-AUTH_PATH = 'auth.cgi'
-CAMERA_PATH = 'camera.cgi'
-STREAMING_PATH = 'SurveillanceStation/videoStreaming.cgi'
-CONTENT_TYPE_HEADER = 'Content-Type'
-
-SYNO_API_URL = '{0}{1}{2}'
 
 PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
     vol.Optional(CONF_NAME, default=DEFAULT_NAME): cv.string,
@@ -62,189 +43,89 @@ def async_setup_platform(hass, config, async_add_devices, discovery_info=None):
     """Set up a Synology IP Camera."""
     verify_ssl = config.get(CONF_VERIFY_SSL)
     timeout = config.get(CONF_TIMEOUT)
-    websession_init = async_get_clientsession(hass, verify_ssl)
-
-    # Determine API to use for authentication
-    syno_api_url = SYNO_API_URL.format(
-        config.get(CONF_URL), WEBAPI_PATH, QUERY_CGI)
-
-    query_payload = {
-        'api': QUERY_API,
-        'method': 'Query',
-        'version': '1',
-        'query': 'SYNO.'
-    }
-    try:
-        with async_timeout.timeout(timeout, loop=hass.loop):
-            query_req = yield from websession_init.get(
-                syno_api_url,
-                params=query_payload
-            )
-
-        # Skip content type check because Synology doesn't return JSON with
-        # right content type
-        query_resp = yield from query_req.json(content_type=None)
-        auth_path = query_resp['data'][AUTH_API]['path']
-        camera_api = query_resp['data'][CAMERA_API]['path']
-        camera_path = query_resp['data'][CAMERA_API]['path']
-        streaming_path = query_resp['data'][STREAMING_API]['path']
-
-    except (asyncio.TimeoutError, aiohttp.ClientError):
-        _LOGGER.exception("Error on %s", syno_api_url)
-        return False
 
-    # Authticate to NAS to get a session id
-    syno_auth_url = SYNO_API_URL.format(
-        config.get(CONF_URL), WEBAPI_PATH, auth_path)
-
-    session_id = yield from get_session_id(
-        hass,
-        websession_init,
-        config.get(CONF_USERNAME),
-        config.get(CONF_PASSWORD),
-        syno_auth_url,
-        timeout
-    )
-
-    # init websession
-    websession = async_create_clientsession(
-        hass, verify_ssl, cookies={'id': session_id})
-
-    # Use SessionID to get cameras in system
-    syno_camera_url = SYNO_API_URL.format(
-        config.get(CONF_URL), WEBAPI_PATH, camera_api)
-
-    camera_payload = {
-        'api': CAMERA_API,
-        'method': 'List',
-        'version': '1'
-    }
     try:
-        with async_timeout.timeout(timeout, loop=hass.loop):
-            camera_req = yield from websession.get(
-                syno_camera_url,
-                params=camera_payload
-            )
-    except (asyncio.TimeoutError, aiohttp.ClientError):
-        _LOGGER.exception("Error on %s", syno_camera_url)
+        from synology.surveillance_station import SurveillanceStation
+        surveillance = SurveillanceStation(
+            config.get(CONF_URL),
+            config.get(CONF_USERNAME),
+            config.get(CONF_PASSWORD),
+            verify_ssl=verify_ssl,
+            timeout=timeout
+        )
+    except (requests.exceptions.RequestException, ValueError):
+        _LOGGER.exception("Error when initializing SurveillanceStation")
         return False
 
-    camera_resp = yield from camera_req.json(content_type=None)
-    cameras = camera_resp['data']['cameras']
+    cameras = surveillance.get_all_cameras()
+    websession = async_create_clientsession(hass, verify_ssl)
 
     # add cameras
     devices = []
     for camera in cameras:
         if not config.get(CONF_WHITELIST):
-            camera_id = camera['id']
-            snapshot_path = camera['snapshot_path']
-
-            device = SynologyCamera(
-                hass, websession, config, camera_id, camera['name'],
-                snapshot_path, streaming_path, camera_path, auth_path, timeout
-            )
+            device = SynologyCamera(websession, surveillance, camera.camera_id)
             devices.append(device)
 
     async_add_devices(devices)
 
 
-@asyncio.coroutine
-def get_session_id(hass, websession, username, password, login_url, timeout):
-    """Get a session id."""
-    auth_payload = {
-        'api': AUTH_API,
-        'method': 'Login',
-        'version': '2',
-        'account': username,
-        'passwd': password,
-        'session': 'SurveillanceStation',
-        'format': 'sid'
-    }
-    try:
-        with async_timeout.timeout(timeout, loop=hass.loop):
-            auth_req = yield from websession.get(
-                login_url,
-                params=auth_payload
-            )
-        auth_resp = yield from auth_req.json(content_type=None)
-        return auth_resp['data']['sid']
-
-    except (asyncio.TimeoutError, aiohttp.ClientError):
-        _LOGGER.exception("Error on %s", login_url)
-        return False
-
-
 class SynologyCamera(Camera):
     """An implementation of a Synology NAS based IP camera."""
 
-    def __init__(self, hass, websession, config, camera_id,
-                 camera_name, snapshot_path, streaming_path, camera_path,
-                 auth_path, timeout):
+    def __init__(self, websession, surveillance, camera_id):
         """Initialize a Synology Surveillance Station camera."""
         super().__init__()
-        self.hass = hass
         self._websession = websession
-        self._name = camera_name
-        self._synology_url = config.get(CONF_URL)
-        self._camera_name = config.get(CONF_CAMERA_NAME)
-        self._stream_id = config.get(CONF_STREAM_ID)
+        self._surveillance = surveillance
         self._camera_id = camera_id
-        self._snapshot_path = snapshot_path
-        self._streaming_path = streaming_path
-        self._camera_path = camera_path
-        self._auth_path = auth_path
-        self._timeout = timeout
+        self._camera = self._surveillance.get_camera(camera_id)
+        self._motion_setting = self._surveillance.get_motion_setting(camera_id)
+        self.is_streaming = self._camera.is_enabled
 
     def camera_image(self):
         """Return bytes of camera image."""
-        return run_coroutine_threadsafe(
-            self.async_camera_image(), self.hass.loop).result()
-
-    @asyncio.coroutine
-    def async_camera_image(self):
-        """Return a still image response from the camera."""
-        image_url = SYNO_API_URL.format(
-            self._synology_url, WEBAPI_PATH, self._camera_path)
-
-        image_payload = {
-            'api': CAMERA_API,
-            'method': 'GetSnapshot',
-            'version': '1',
-            'cameraId': self._camera_id
-        }
-        try:
-            with async_timeout.timeout(self._timeout, loop=self.hass.loop):
-                response = yield from self._websession.get(
-                    image_url,
-                    params=image_payload
-                )
-        except (asyncio.TimeoutError, aiohttp.ClientError):
-            _LOGGER.error("Error fetching %s", image_url)
-            return None
-
-        image = yield from response.read()
-
-        return image
+        return self._surveillance.get_camera_image(self._camera_id)
 
     @asyncio.coroutine
     def handle_async_mjpeg_stream(self, request):
         """Return a MJPEG stream image response directly from the camera."""
-        streaming_url = SYNO_API_URL.format(
-            self._synology_url, WEBAPI_PATH, self._streaming_path)
-
-        streaming_payload = {
-            'api': STREAMING_API,
-            'method': 'Stream',
-            'version': '1',
-            'cameraId': self._camera_id,
-            'format': 'mjpeg'
-        }
-        stream_coro = self._websession.get(
-            streaming_url, params=streaming_payload)
+        streaming_url = self._camera.video_stream_url
+        stream_coro = self._websession.get(streaming_url)
 
         yield from async_aiohttp_proxy_web(self.hass, request, stream_coro)
 
     @property
     def name(self):
         """Return the name of this device."""
-        return self._name
+        return self._camera.name
+
+    @property
+    def is_recording(self):
+        """Return true if the device is recording."""
+        return self._camera.is_recording
+
+    def should_poll(self):
+        """Update the recording state periodically."""
+        return True
+
+    def update(self):
+        """Update the status of the camera."""
+        self._surveillance.update()
+        self._camera = self._surveillance.get_camera(self._camera.camera_id)
+        self._motion_setting = self._surveillance.get_motion_setting(
+            self._camera.camera_id)
+        self.is_streaming = self._camera.is_enabled
+
+    @property
+    def motion_detection_enabled(self):
+        """Return the camera motion detection status."""
+        return self._motion_setting.is_enabled
+
+    def enable_motion_detection(self):
+        """Enable motion detection in the camera."""
+        self._surveillance.enable_motion_detection(self._camera_id)
+
+    def disable_motion_detection(self):
+        """Disable motion detection in camera."""
+        self._surveillance.disable_motion_detection(self._camera_id)
diff --git a/requirements_all.txt b/requirements_all.txt
index 7308df478338a536cdae770331f03f8a9832ee3a..d74edac0c9fdb63f8419169f2ab894338b9c3e26 100644
--- a/requirements_all.txt
+++ b/requirements_all.txt
@@ -539,6 +539,9 @@ pwmled==1.2.1
 # homeassistant.components.sensor.cpuspeed
 py-cpuinfo==3.3.0
 
+# homeassistant.components.camera.synology
+py-synology==0.1.1
+
 # homeassistant.components.hdmi_cec
 pyCEC==0.4.13