diff --git a/debian/control b/debian/control
index 95594410..e1975c7a 100644
--- a/debian/control
+++ b/debian/control
@@ -276,6 +276,22 @@ Description: nymea.io plugin for elgato
This package will install the nymea.io plugin for elgato
+Package: nymea-plugin-fastcom
+Architecture: any
+Depends: ${misc:Depends},
+ nymea-plugins-translations,
+ python3-pip,
+Description: nymea.io plugin for fast.com based internet speed test
+ The nymea daemon is a plugin based IoT (Internet of Things) server. The
+ server works like a translator for devices, things and services and
+ allows them to interact.
+ With the powerful rule engine you are able to connect any device available
+ in the system and create individual scenes and behaviors for your environment.
+ .
+ This package will install the nymea.io plugin for performing ineternet speed
+ tests using fast.com
+
+
Package: nymea-plugin-flowercare
Architecture: any
Depends: ${shlibs:Depends},
diff --git a/debian/nymea-plugin-fastcom.install.in b/debian/nymea-plugin-fastcom.install.in
new file mode 100644
index 00000000..f5a308b1
--- /dev/null
+++ b/debian/nymea-plugin-fastcom.install.in
@@ -0,0 +1,3 @@
+fastcom/integrationpluginfastcom.json usr/lib/@DEB_HOST_MULTIARCH@/nymea/plugins/fastcom/
+fastcom/integrationpluginfastcom.py usr/lib/@DEB_HOST_MULTIARCH@/nymea/plugins/fastcom/
+fastcom/requirements.txt usr/lib/@DEB_HOST_MULTIARCH@/nymea/plugins/fastcom/
diff --git a/fastcom/README.md b/fastcom/README.md
new file mode 100644
index 00000000..3009624f
--- /dev/null
+++ b/fastcom/README.md
@@ -0,0 +1,6 @@
+# Fast.com
+
+A nymea plugin to monitor your internet connection speed using fast.com servers.
+
+The speed test can be triggered manually, or configured to automatically run after
+a specified interval.
diff --git a/fastcom/fastcom.pro b/fastcom/fastcom.pro
new file mode 100644
index 00000000..54c80fe4
--- /dev/null
+++ b/fastcom/fastcom.pro
@@ -0,0 +1,4 @@
+TEMPLATE = aux
+
+OTHER_FILES = integrationpluginfastcom.py \
+ integrationpluginfastcom.json
diff --git a/fastcom/fastcom.svg b/fastcom/fastcom.svg
new file mode 100644
index 00000000..e37e9627
--- /dev/null
+++ b/fastcom/fastcom.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/fastcom/integrationpluginfastcom.json b/fastcom/integrationpluginfastcom.json
new file mode 100644
index 00000000..86a556ce
--- /dev/null
+++ b/fastcom/integrationpluginfastcom.json
@@ -0,0 +1,83 @@
+{
+ "id": "142bdfae-43b1-4915-8906-99949e0a6f85",
+ "name": "fastcom",
+ "displayName": "fast.com speed test",
+ "vendors": [
+ {
+ "id": "8ff41f1e-0aa4-4b86-a959-2c54dc9c716c",
+ "name": "fastcom",
+ "displayName": "fast.com",
+ "thingClasses": [
+ {
+ "id": "dcd2d320-18b2-4655-8188-dd46a1c27360",
+ "name": "speedtest",
+ "displayName": "Internet connection speed test",
+ "createMethods": ["user"],
+ "setupMethod": "justAdd",
+ "settingsTypes": [
+ {
+ "id": "12646890-9335-4c4e-ada2-ac9e603c4f2c",
+ "name": "interval",
+ "displayName": "Interval for speed tests",
+ "type": "uint",
+ "unit": "Minutes",
+ "defaultValue": 60
+ }
+ ],
+ "eventTypes": [
+ {
+ "id": "c29dcc25-40b1-4db8-a8ad-6552b2813ee8",
+ "name": "testCompleted",
+ "displayName": "Test run completed",
+ "paramTypes": [
+ {
+ "id": "3d101deb-a3b7-451c-ad07-02ff38afd617",
+ "name": "result",
+ "displayName": "Test result",
+ "type": "double",
+ "defaultValue": 0
+ }
+ ]
+ }
+ ],
+ "stateTypes": [
+ {
+ "id": "07c2bddd-6e5c-4fa0-a114-9393adb6cb65",
+ "name": "lastResult",
+ "displayName": "Last result",
+ "displayNameEvent": "Last result changed",
+ "type": "double",
+ "defaultValue": 0
+ },
+ {
+ "id": "9ad90ce5-3d66-4469-8d04-4e6bfc132db4",
+ "name": "testRunning",
+ "displayName": "Test is running",
+ "displayNameEvent": "Test started or stopped",
+ "type": "bool",
+ "defaultValue": false,
+ "cached": false
+ }
+ ],
+ "actionTypes": [
+ {
+ "id": "7f77a7cf-3ba1-4119-959d-9d652449d1fb",
+ "name": "runTest",
+ "displayName": "Run test",
+ "paramTypes": [
+ {
+ "id": "af5f3b43-2c60-4330-a82d-20b98fac9096",
+ "name": "duration",
+ "displayName": "Duration",
+ "type": "int",
+ "unit": "Seconds",
+ "defaultValue": 15
+ }
+ ]
+ }
+ ]
+ }
+ ]
+ }
+ ]
+}
diff --git a/fastcom/integrationpluginfastcom.py b/fastcom/integrationpluginfastcom.py
new file mode 100755
index 00000000..78aa09cd
--- /dev/null
+++ b/fastcom/integrationpluginfastcom.py
@@ -0,0 +1,91 @@
+# Copyright 2013 - 2020, nymea GmbH
+# Contact: contact@nymea.io
+#
+# This file is part of nymea.
+# This project including source code and documentation is protected by
+# copyright law, and remains the property of nymea GmbH. All rights, including
+# reproduction, publication, editing and translation, are reserved. The use of
+# this project is subject to the terms of a license agreement to be concluded
+# with nymea GmbH in accordance with the terms of use of nymea GmbH, available
+# under https://nymea.io/license
+#
+# GNU Lesser General Public License Usage
+# Alternatively, this project may be redistributed and/or modified under the
+# terms of the GNU Lesser General Public License as published by the Free
+# Software Foundation; version 3. This project is distributed in the hope that
+# it will be useful, but WITHOUT ANY WARRANTY; without even the implied
+# warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with this project. If not, see .
+#
+# For any further details and any questions please contact us under
+# contact@nymea.io or see our FAQ/Licensing Information on
+# https://nymea.io/license/faq
+
+import nymea
+from fastdotcom import fast_com
+import threading
+
+timers = {}
+
+def init():
+ logger.log("fast.com init")
+
+
+def deinit():
+ for timer in timers:
+ timers[timer].cancel()
+
+
+def setupThing(info):
+ logger.log("setupThing", info.thing.name, "Scheduling speed test in 10 seconds.")
+ info.thing.nameChangedHandler = nameChanged
+ timers[info.thing] = threading.Timer(10, runTestForever, [info.thing])
+ timers[info.thing].start()
+ info.finish(nymea.ThingErrorNoError)
+
+def postSetupThing(thing):
+ logger.log("postSetupThing", thing)
+
+
+def nameChanged(thing):
+ logger.log("Thing name changed:", thing.name)
+
+
+def thingRemoved(thing):
+ logger.log("thingRemoved:", thing.name)
+ timers[thing].cancel()
+ del timers[thing]
+
+
+def executeAction(info):
+ logger.log("executeAction")
+ if info.actionTypeId == speedtestRunTestActionTypeId:
+ if info.thing.stateValue(speedtestTestRunningStateTypeId) == True:
+ info.finish(nymea.ThingErrorThingInUse, "A speed test is already running")
+ return
+ info.finish(nymea.ThingErrorNoError)
+ runTest(info.thing, duration=info.paramValue(speedtestRunTestActionDurationParamTypeId))
+
+
+def runTest(thing, duration=10):
+ logger.log("Running speed test for:", thing.name, "with maximum duration", duration)
+ thing.setStateValue(speedtestTestRunningStateTypeId, True)
+ result = fast_com(maxtime=duration, verbose=True)
+ thing.setStateValue(speedtestLastResultStateTypeId, result)
+ logger.log("Speed test result:", result)
+ thing.setStateValue(speedtestTestRunningStateTypeId, False)
+ param = nymea.Param(speedtestTestCompletedEventResultParamTypeId, result)
+ params = [param]
+ thing.emitEvent(speedtestTestCompletedEventTypeId, params)
+ logger.log("all done")
+
+
+def runTestForever(thing):
+ del timers[thing]
+ runTest(thing)
+ logger.log("Running next test in %i minutes." % thing.settings[0].value)
+ timers[thing] = threading.Timer(thing.settings[0].value * 60, runTestForever, [thing])
+ timers[thing].start()
diff --git a/fastcom/meta.json b/fastcom/meta.json
new file mode 100644
index 00000000..b4e03a4d
--- /dev/null
+++ b/fastcom/meta.json
@@ -0,0 +1,13 @@
+{
+ "title": "fast.com",
+ "tagline": "Monitor your internet connection speed",
+ "icon": "fastcom.svg",
+ "stability": "consumer",
+ "offline": false,
+ "technologies": [
+ "cloud"
+ ],
+ "categories": [
+ "online-service"
+ ]
+}
diff --git a/fastcom/requirements.txt b/fastcom/requirements.txt
new file mode 100644
index 00000000..8cea8274
--- /dev/null
+++ b/fastcom/requirements.txt
@@ -0,0 +1,15 @@
+
+fastdotcom==0.0.3 \
+ --hash=sha256:84647d665119cfbef01bf785607b85d7a29353208605ca53a4155c331e407cd6 \
+ --hash=sha256:c77689b5595e0ef89d60d5d3a2f669ef2f158d2868fda65e1201d91b53e013b3
+requests==2.24.0 \
+ --hash=sha256:b3559a131db72c33ee969480840fff4bb6dd111de7dd27c8ee1f820f4f00231b \
+ --hash=sha256:fe75cc94a9443b9246fc7049224f75604b113c36acb93f87b80ed42c44cbb898
+certifi==2017.4.17 \
+ --hash=sha256:f4318671072f030a33c7ca6acaef720ddd50ff124d1388e50c1bda4cbd6d7010
+idna==2.10 \
+ --hash=sha256:b97d804b1e9b523befed77c48dacec60e6dcb0b5391d57af6a65a312a90648c0
+chardet==3.0.4 \
+ --hash=sha256:fc323ffcaeaed0e0a02bf4d117757b98aed530d9ed4531e3e15460124c106691
+urllib3==1.25.10 \
+ --hash=sha256:e7983572181f5e1522d9c98453462384ee92a0be7fac5f1413a1e35c56cc0461
diff --git a/fastcom/translations/142bdfae-43b1-4915-8906-99949e0a6f85-en_US.ts b/fastcom/translations/142bdfae-43b1-4915-8906-99949e0a6f85-en_US.ts
new file mode 100644
index 00000000..65261928
--- /dev/null
+++ b/fastcom/translations/142bdfae-43b1-4915-8906-99949e0a6f85-en_US.ts
@@ -0,0 +1,85 @@
+
+
+
+
+ fastcom
+
+
+ Duration
+ The name of the ParamType (ThingClass: speedtest, ActionType: runTest, ID: {af5f3b43-2c60-4330-a82d-20b98fac9096})
+
+
+
+
+ Internet connection speed test
+ The name of the ThingClass ({dcd2d320-18b2-4655-8188-dd46a1c27360})
+
+
+
+
+ Interval for speed tests
+ The name of the ParamType (ThingClass: speedtest, Type: settings, ID: {12646890-9335-4c4e-ada2-ac9e603c4f2c})
+
+
+
+
+
+ Last result
+ The name of the ParamType (ThingClass: speedtest, EventType: lastResult, ID: {07c2bddd-6e5c-4fa0-a114-9393adb6cb65})
+----------
+The name of the StateType ({07c2bddd-6e5c-4fa0-a114-9393adb6cb65}) of ThingClass speedtest
+
+
+
+
+ Last result changed
+ The name of the EventType ({07c2bddd-6e5c-4fa0-a114-9393adb6cb65}) of ThingClass speedtest
+
+
+
+
+ Run test
+ The name of the ActionType ({7f77a7cf-3ba1-4119-959d-9d652449d1fb}) of ThingClass speedtest
+
+
+
+
+
+ Test is running
+ The name of the ParamType (ThingClass: speedtest, EventType: testRunning, ID: {9ad90ce5-3d66-4469-8d04-4e6bfc132db4})
+----------
+The name of the StateType ({9ad90ce5-3d66-4469-8d04-4e6bfc132db4}) of ThingClass speedtest
+
+
+
+
+ Test result
+ The name of the ParamType (ThingClass: speedtest, EventType: testCompleted, ID: {3d101deb-a3b7-451c-ad07-02ff38afd617})
+
+
+
+
+ Test run completed
+ The name of the EventType ({c29dcc25-40b1-4db8-a8ad-6552b2813ee8}) of ThingClass speedtest
+
+
+
+
+ Test started or stopped
+ The name of the EventType ({9ad90ce5-3d66-4469-8d04-4e6bfc132db4}) of ThingClass speedtest
+
+
+
+
+ fast.com
+ The name of the vendor ({8ff41f1e-0aa4-4b86-a959-2c54dc9c716c})
+
+
+
+
+ fast.com speed test
+ The name of the plugin fastcom ({142bdfae-43b1-4915-8906-99949e0a6f85})
+
+
+
+
diff --git a/nymea-plugins.pro b/nymea-plugins.pro
index c3537adb..1194d487 100644
--- a/nymea-plugins.pro
+++ b/nymea-plugins.pro
@@ -18,6 +18,7 @@ PLUGIN_DIRS = \
dynatrace \
elgato \
eq-3 \
+ fastcom \
flowercare \
fronius \
genericelements \
diff --git a/sunposition/integrationpluginsunposition.py b/sunposition/integrationpluginsunposition.py
index 0b42142a..b638d129 100644
--- a/sunposition/integrationpluginsunposition.py
+++ b/sunposition/integrationpluginsunposition.py
@@ -48,6 +48,7 @@ def init():
logger.log("Updating thing", thing.name, "Angle:", angle)
thing.setStateValue(sunPositionAngleStateTypeId, angle)
+
def deinit():
global loopRunning
loopRunning = False