{"action":"created","comment":{"url":"https://api.github.com/repos/openhab/openhab/pulls/comments/74697564","id":74697564,"diff_hunk":"@@ -68,142 +74,170 @@ protected void removeBindingProvider(PlugwiseBindingProvider bindingProvider) {\n         super.removeBindingProvider(bindingProvider);\n     }\n \n-    @SuppressWarnings(\"rawtypes\")\n     @Override\n-    public void updated(Dictionary config) throws ConfigurationException {\n+    public void updated(Dictionary<String, ?> config) throws ConfigurationException {\n \n-        if (config != null) {\n+        if (config == null) {\n+            return;\n+        }\n \n-            // First of all make sure the Stick gets set up\n-            Enumeration keys = config.keys();\n-            while (keys.hasMoreElements()) {\n+        validateKeyPatternsInConfig(config);\n \n-                String key = (String) keys.nextElement();\n+        stick = setupStick(config);\n \n-                // the config-key enumeration contains additional keys that we\n-                // don't want to process here ...\n-                if (\"service.pid\".equals(key)) {\n-                    continue;\n-                }\n+        if (stick != null) {\n+            setupNonStickDevices(config);\n+            setProperlyConfigured(true);\n+        } else {\n+            logger.error(\"Plugwise needs at least one Stick in order to operate\");\n+        }\n \n-                Matcher matcher = EXTRACT_PLUGWISE_CONFIG_PATTERN.matcher(key);\n-                if (!matcher.matches()) {\n-                    logger.error(\"given plugwise-config-key '\" + key\n-                            + \"' does not follow the expected pattern '<PlugwiseId>.<mac|port|interval>'\");\n-                    continue;\n-                }\n+    }\n \n-                matcher.reset();\n-                matcher.find();\n+    private Stick setupStick(Dictionary<String, ?> config) {\n \n-                String plugwiseID = matcher.group(1);\n+        String port = (String) config.get(\"stick.port\");\n \n-                if (plugwiseID.equals(\"stick\")) {\n-                    if (stick == null) {\n+        if (port == null) {\n+            return null;\n+        }\n \n-                        String configKey = matcher.group(2);\n-                        String value = (String) config.get(key);\n+        Stick stick = new Stick(port, this);\n+        logger.info(\"Plugwise added Stick connected to serial port {}\", port);\n \n-                        if (\"port\".equals(configKey)) {\n-                            stick = new Stick(value, this);\n-                            logger.info(\"Plugwise added Stick connected to serial port {}\", value);\n-                        } else if (\"interval\".equals(configKey)) {\n-                            // do nothing for now. we will set in the second run\n-                        } else if (\"retries\".equals(configKey)) {\n-                            // do nothing for now. we will set in the second run\n-                        }\n+        String interval = (String) config.get(\"stick.interval\");\n+        if (interval != null) {\n+            stick.setInterval(Integer.valueOf(interval));\n+            logger.info(\"Setting the interval to send ZigBee PDUs to {} ms\", interval);\n+        }\n \n-                        else {\n-                            throw new ConfigurationException(configKey,\n-                                    \"the given configKey '\" + configKey + \"' is unknown\");\n-                        }\n-                    }\n-                }\n+        String retries = (String) config.get(\"stick.retries\");\n+        if (retries != null) {\n+            stick.setRetries(Integer.valueOf(retries));\n+            logger.info(\"Setting the maximum number of attempts to send a message to \", retries);\n+        }\n+\n+        return stick;\n+    }\n+\n+    private void setupNonStickDevices(Dictionary<String, ?> config) {\n+\n+        Set<String> deviceNames = getDeviceNamesFromConfig(config);\n \n+        for (String deviceName : deviceNames) {\n+            if (\"stick\".equals(deviceName)) {\n+                continue;\n             }\n \n-            if (stick != null) {\n-                // re-run through the configuration and setup the remaining devices\n-                keys = config.keys();\n-                while (keys.hasMoreElements()) {\n+            if (stick.getDeviceByName(deviceName) != null) {\n+                continue;\n+            }\n \n-                    String key = (String) keys.nextElement();\n+            String MAC = (String) config.get(deviceName + \".mac\");\n+            if (MAC == null || MAC.equals(\"\")) {\n+                logger.error(\"Plugwise can not add device with name {} without a MAC address\", deviceName);\n+            } else if (stick.getDeviceByMAC(MAC) != null) {\n+                logger.error(\n+                        \"Plugwise can not add device with name: {} and MAC address: {}, \"\n+                                + \"the same MAC address is already used by device with name: {}\",\n+                        deviceName, MAC, stick.getDeviceByMAC(MAC).name);\n+            } else {\n+                String deviceType = (String) config.get(deviceName + \".type\");\n+                PlugwiseDevice device = createPlugwiseDevice(deviceType, MAC, deviceName);\n \n-                    // the config-key enumeration contains additional keys that we\n-                    // don't want to process here ...\n-                    if (\"service.pid\".equals(key)) {\n-                        continue;\n-                    }\n+                if (device != null) {\n+                    stick.plugwiseDeviceCache.add(device);\n+                }\n+            }\n \n-                    Matcher matcher = EXTRACT_PLUGWISE_CONFIG_PATTERN.matcher(key);\n-                    if (!matcher.matches()) {\n-                        logger.error(\"given plugwise-config-key '\" + key\n-                                + \"' does not follow the expected pattern '<PlugwiseId>.<mac|port>'\");\n-                        continue;\n-                    }\n+        }\n \n-                    matcher.reset();\n-                    matcher.find();\n+    }\n \n-                    String plugwiseID = matcher.group(1);\n+    private PlugwiseDevice createPlugwiseDevice(String deviceType, String MAC, String deviceName) {\n+\n+        PlugwiseDevice device = null;\n+\n+        if (\"circleplus\".equals(deviceType) || \"circleplus\".equals(deviceName)) {\n+            // for backwards compatibility a device with the name 'circleplus' always creates a CirclePlus\n+            device = new CirclePlus(MAC, stick, deviceName);\n+            logger.info(\"Plugwise created Circle+ with name: {} and MAC address: {}\", deviceName, MAC);\n+        } else if (\"circle\".equals(deviceType) || deviceType == null) {\n+            // for backwards compatibility a device without a deviceType always creates a Circle\n+            device = new Circle(MAC, stick, deviceName);\n+            logger.info(\"Plugwise created Circle with name: {} and MAC address: {}\", deviceName, MAC);\n+        } else if (\"scan\".equals(deviceType)) {\n+            device = new Scan(MAC, stick, deviceName);\n+            logger.info(\"Plugwise created Scan with name: {} and MAC address: {}\", deviceName, MAC);\n+        } else if (\"sense\".equals(deviceType)) {\n+            device = new Sense(MAC, stick, deviceName);\n+            logger.info(\"Plugwise created Sense with name: {} and MAC address: {}\", deviceName, MAC);\n+        } else if (\"stealth\".equals(deviceType)) {\n+            device = new Stealth(MAC, stick, deviceName);\n+            logger.info(\"Plugwise created Stealth with name: {} and MAC address: {}\", deviceName, MAC);\n+        } else if (\"switch\".equals(deviceType)) {\n+            device = new Switch(MAC, stick, deviceName);\n+            logger.info(\"Plugwise created Switch with name: {} and MAC address: {}\", deviceName, MAC);\n+        } else {\n+            logger.error(\n+                    \"Plugwise can not create device with name: '{}' because it has an unknown device type: '{}'. \"\n+                            + \"Known device types are: circle|circleplus|scan|sense|stealth|switch\",\n+                    deviceName, deviceType);\n+        }\n+        return device;\n+    }","path":"bundles/binding/org.openhab.binding.plugwise/src/main/java/org/openhab/binding/plugwise/internal/PlugwiseBinding.java","position":201,"original_position":201,"commit_id":"c8467349270b790fe1f69ba29a252bcfb2494ea4","original_commit_id":"c8467349270b790fe1f69ba29a252bcfb2494ea4","user":{"login":"watou","id":3008217,"avatar_url":"https://avatars.githubusercontent.com/u/3008217?v=3","gravatar_id":"","url":"https://api.github.com/users/watou","html_url":"https://github.com/watou","followers_url":"https://api.github.com/users/watou/followers","following_url":"https://api.github.com/users/watou/following{/other_user}","gists_url":"https://api.github.com/users/watou/gists{/gist_id}","starred_url":"https://api.github.com/users/watou/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/watou/subscriptions","organizations_url":"https://api.github.com/users/watou/orgs","repos_url":"https://api.github.com/users/watou/repos","events_url":"https://api.github.com/users/watou/events{/privacy}","received_events_url":"https://api.github.com/users/watou/received_events","type":"User","site_admin":false},"body":"`logger.info` -> `logger.debug` or `logger.trace`\r\n\r\n`logger.error` -> `logger.warn` unless system stability is affected","created_at":"2016-08-14T08:04:02Z","updated_at":"2016-08-14T08:04:02Z","html_url":"https://github.com/openhab/openhab/pull/4586#discussion_r74697564","pull_request_url":"https://api.github.com/repos/openhab/openhab/pulls/4586","_links":{"self":{"href":"https://api.github.com/repos/openhab/openhab/pulls/comments/74697564"},"html":{"href":"https://github.com/openhab/openhab/pull/4586#discussion_r74697564"},"pull_request":{"href":"https://api.github.com/repos/openhab/openhab/pulls/4586"}}},"pull_request":{"url":"https://api.github.com/repos/openhab/openhab/pulls/4586","id":81228712,"html_url":"https://github.com/openhab/openhab/pull/4586","diff_url":"https://github.com/openhab/openhab/pull/4586.diff","patch_url":"https://github.com/openhab/openhab/pull/4586.patch","issue_url":"https://api.github.com/repos/openhab/openhab/issues/4586","number":4586,"state":"open","locked":false,"title":"[Plugwise] Add support for Scan, Sense, Stealth and Switch #4565","user":{"login":"wborn","id":12213581,"avatar_url":"https://avatars.githubusercontent.com/u/12213581?v=3","gravatar_id":"","url":"https://api.github.com/users/wborn","html_url":"https://github.com/wborn","followers_url":"https://api.github.com/users/wborn/followers","following_url":"https://api.github.com/users/wborn/following{/other_user}","gists_url":"https://api.github.com/users/wborn/gists{/gist_id}","starred_url":"https://api.github.com/users/wborn/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/wborn/subscriptions","organizations_url":"https://api.github.com/users/wborn/orgs","repos_url":"https://api.github.com/users/wborn/repos","events_url":"https://api.github.com/users/wborn/events{/privacy}","received_events_url":"https://api.github.com/users/wborn/received_events","type":"User","site_admin":false},"body":"My implementation for this enhancement (#4565) has been working fine for several weeks now so here is the pull request.","created_at":"2016-08-13T22:39:32Z","updated_at":"2016-08-14T08:04:02Z","closed_at":null,"merged_at":null,"merge_commit_sha":"1f7d2d51f202cc09143bd3f3f855bd75c75e9117","assignee":null,"assignees":[],"milestone":null,"commits_url":"https://api.github.com/repos/openhab/openhab/pulls/4586/commits","review_comments_url":"https://api.github.com/repos/openhab/openhab/pulls/4586/comments","review_comment_url":"https://api.github.com/repos/openhab/openhab/pulls/comments{/number}","comments_url":"https://api.github.com/repos/openhab/openhab/issues/4586/comments","statuses_url":"https://api.github.com/repos/openhab/openhab/statuses/c8467349270b790fe1f69ba29a252bcfb2494ea4","head":{"label":"wborn:4565-add-support-for-scan-sense-stealth-and-switch","ref":"4565-add-support-for-scan-sense-stealth-and-switch","sha":"c8467349270b790fe1f69ba29a252bcfb2494ea4","user":{"login":"wborn","id":12213581,"avatar_url":"https://avatars.githubusercontent.com/u/12213581?v=3","gravatar_id":"","url":"https://api.github.com/users/wborn","html_url":"https://github.com/wborn","followers_url":"https://api.github.com/users/wborn/followers","following_url":"https://api.github.com/users/wborn/following{/other_user}","gists_url":"https://api.github.com/users/wborn/gists{/gist_id}","starred_url":"https://api.github.com/users/wborn/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/wborn/subscriptions","organizations_url":"https://api.github.com/users/wborn/orgs","repos_url":"https://api.github.com/users/wborn/repos","events_url":"https://api.github.com/users/wborn/events{/privacy}","received_events_url":"https://api.github.com/users/wborn/received_events","type":"User","site_admin":false},"repo":{"id":64964341,"name":"openhab","full_name":"wborn/openhab","owner":{"login":"wborn","id":12213581,"avatar_url":"https://avatars.githubusercontent.com/u/12213581?v=3","gravatar_id":"","url":"https://api.github.com/users/wborn","html_url":"https://github.com/wborn","followers_url":"https://api.github.com/users/wborn/followers","following_url":"https://api.github.com/users/wborn/following{/other_user}","gists_url":"https://api.github.com/users/wborn/gists{/gist_id}","starred_url":"https://api.github.com/users/wborn/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/wborn/subscriptions","organizations_url":"https://api.github.com/users/wborn/orgs","repos_url":"https://api.github.com/users/wborn/repos","events_url":"https://api.github.com/users/wborn/events{/privacy}","received_events_url":"https://api.github.com/users/wborn/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/wborn/openhab","description":"Source code of the open Home Automation Bus (openHAB)","fork":true,"url":"https://api.github.com/repos/wborn/openhab","forks_url":"https://api.github.com/repos/wborn/openhab/forks","keys_url":"https://api.github.com/repos/wborn/openhab/keys{/key_id}","collaborators_url":"https://api.github.com/repos/wborn/openhab/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/wborn/openhab/teams","hooks_url":"https://api.github.com/repos/wborn/openhab/hooks","issue_events_url":"https://api.github.com/repos/wborn/openhab/issues/events{/number}","events_url":"https://api.github.com/repos/wborn/openhab/events","assignees_url":"https://api.github.com/repos/wborn/openhab/assignees{/user}","branches_url":"https://api.github.com/repos/wborn/openhab/branches{/branch}","tags_url":"https://api.github.com/repos/wborn/openhab/tags","blobs_url":"https://api.github.com/repos/wborn/openhab/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/wborn/openhab/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/wborn/openhab/git/refs{/sha}","trees_url":"https://api.github.com/repos/wborn/openhab/git/trees{/sha}","statuses_url":"https://api.github.com/repos/wborn/openhab/statuses/{sha}","languages_url":"https://api.github.com/repos/wborn/openhab/languages","stargazers_url":"https://api.github.com/repos/wborn/openhab/stargazers","contributors_url":"https://api.github.com/repos/wborn/openhab/contributors","subscribers_url":"https://api.github.com/repos/wborn/openhab/subscribers","subscription_url":"https://api.github.com/repos/wborn/openhab/subscription","commits_url":"https://api.github.com/repos/wborn/openhab/commits{/sha}","git_commits_url":"https://api.github.com/repos/wborn/openhab/git/commits{/sha}","comments_url":"https://api.github.com/repos/wborn/openhab/comments{/number}","issue_comment_url":"https://api.github.com/repos/wborn/openhab/issues/comments{/number}","contents_url":"https://api.github.com/repos/wborn/openhab/contents/{+path}","compare_url":"https://api.github.com/repos/wborn/openhab/compare/{base}...{head}","merges_url":"https://api.github.com/repos/wborn/openhab/merges","archive_url":"https://api.github.com/repos/wborn/openhab/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/wborn/openhab/downloads","issues_url":"https://api.github.com/repos/wborn/openhab/issues{/number}","pulls_url":"https://api.github.com/repos/wborn/openhab/pulls{/number}","milestones_url":"https://api.github.com/repos/wborn/openhab/milestones{/number}","notifications_url":"https://api.github.com/repos/wborn/openhab/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/wborn/openhab/labels{/name}","releases_url":"https://api.github.com/repos/wborn/openhab/releases{/id}","deployments_url":"https://api.github.com/repos/wborn/openhab/deployments","created_at":"2016-08-04T20:16:50Z","updated_at":"2016-08-04T20:17:05Z","pushed_at":"2016-08-13T22:30:20Z","git_url":"git://github.com/wborn/openhab.git","ssh_url":"git@github.com:wborn/openhab.git","clone_url":"https://github.com/wborn/openhab.git","svn_url":"https://github.com/wborn/openhab","homepage":null,"size":202673,"stargazers_count":0,"watchers_count":0,"language":"Java","has_issues":false,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":0,"mirror_url":null,"open_issues_count":0,"forks":0,"open_issues":0,"watchers":0,"default_branch":"master"}},"base":{"label":"openhab:master","ref":"master","sha":"0b439ef742bb92af43f0dd4df5bfb16039269b25","user":{"login":"openhab","id":1007353,"avatar_url":"https://avatars.githubusercontent.com/u/1007353?v=3","gravatar_id":"","url":"https://api.github.com/users/openhab","html_url":"https://github.com/openhab","followers_url":"https://api.github.com/users/openhab/followers","following_url":"https://api.github.com/users/openhab/following{/other_user}","gists_url":"https://api.github.com/users/openhab/gists{/gist_id}","starred_url":"https://api.github.com/users/openhab/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/openhab/subscriptions","organizations_url":"https://api.github.com/users/openhab/orgs","repos_url":"https://api.github.com/users/openhab/repos","events_url":"https://api.github.com/users/openhab/events{/privacy}","received_events_url":"https://api.github.com/users/openhab/received_events","type":"Organization","site_admin":false},"repo":{"id":12983151,"name":"openhab","full_name":"openhab/openhab","owner":{"login":"openhab","id":1007353,"avatar_url":"https://avatars.githubusercontent.com/u/1007353?v=3","gravatar_id":"","url":"https://api.github.com/users/openhab","html_url":"https://github.com/openhab","followers_url":"https://api.github.com/users/openhab/followers","following_url":"https://api.github.com/users/openhab/following{/other_user}","gists_url":"https://api.github.com/users/openhab/gists{/gist_id}","starred_url":"https://api.github.com/users/openhab/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/openhab/subscriptions","organizations_url":"https://api.github.com/users/openhab/orgs","repos_url":"https://api.github.com/users/openhab/repos","events_url":"https://api.github.com/users/openhab/events{/privacy}","received_events_url":"https://api.github.com/users/openhab/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/openhab/openhab","description":"Source code of the open Home Automation Bus (openHAB)","fork":false,"url":"https://api.github.com/repos/openhab/openhab","forks_url":"https://api.github.com/repos/openhab/openhab/forks","keys_url":"https://api.github.com/repos/openhab/openhab/keys{/key_id}","collaborators_url":"https://api.github.com/repos/openhab/openhab/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/openhab/openhab/teams","hooks_url":"https://api.github.com/repos/openhab/openhab/hooks","issue_events_url":"https://api.github.com/repos/openhab/openhab/issues/events{/number}","events_url":"https://api.github.com/repos/openhab/openhab/events","assignees_url":"https://api.github.com/repos/openhab/openhab/assignees{/user}","branches_url":"https://api.github.com/repos/openhab/openhab/branches{/branch}","tags_url":"https://api.github.com/repos/openhab/openhab/tags","blobs_url":"https://api.github.com/repos/openhab/openhab/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/openhab/openhab/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/openhab/openhab/git/refs{/sha}","trees_url":"https://api.github.com/repos/openhab/openhab/git/trees{/sha}","statuses_url":"https://api.github.com/repos/openhab/openhab/statuses/{sha}","languages_url":"https://api.github.com/repos/openhab/openhab/languages","stargazers_url":"https://api.github.com/repos/openhab/openhab/stargazers","contributors_url":"https://api.github.com/repos/openhab/openhab/contributors","subscribers_url":"https://api.github.com/repos/openhab/openhab/subscribers","subscription_url":"https://api.github.com/repos/openhab/openhab/subscription","commits_url":"https://api.github.com/repos/openhab/openhab/commits{/sha}","git_commits_url":"https://api.github.com/repos/openhab/openhab/git/commits{/sha}","comments_url":"https://api.github.com/repos/openhab/openhab/comments{/number}","issue_comment_url":"https://api.github.com/repos/openhab/openhab/issues/comments{/number}","contents_url":"https://api.github.com/repos/openhab/openhab/contents/{+path}","compare_url":"https://api.github.com/repos/openhab/openhab/compare/{base}...{head}","merges_url":"https://api.github.com/repos/openhab/openhab/merges","archive_url":"https://api.github.com/repos/openhab/openhab/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/openhab/openhab/downloads","issues_url":"https://api.github.com/repos/openhab/openhab/issues{/number}","pulls_url":"https://api.github.com/repos/openhab/openhab/pulls{/number}","milestones_url":"https://api.github.com/repos/openhab/openhab/milestones{/number}","notifications_url":"https://api.github.com/repos/openhab/openhab/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/openhab/openhab/labels{/name}","releases_url":"https://api.github.com/repos/openhab/openhab/releases{/id}","deployments_url":"https://api.github.com/repos/openhab/openhab/deployments","created_at":"2013-09-20T20:28:43Z","updated_at":"2016-08-13T17:16:36Z","pushed_at":"2016-08-13T22:39:33Z","git_url":"git://github.com/openhab/openhab.git","ssh_url":"git@github.com:openhab/openhab.git","clone_url":"https://github.com/openhab/openhab.git","svn_url":"https://github.com/openhab/openhab","homepage":null,"size":298786,"stargazers_count":2887,"watchers_count":2887,"language":"Java","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":1414,"mirror_url":null,"open_issues_count":325,"forks":1414,"open_issues":325,"watchers":2887,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/openhab/openhab/pulls/4586"},"html":{"href":"https://github.com/openhab/openhab/pull/4586"},"issue":{"href":"https://api.github.com/repos/openhab/openhab/issues/4586"},"comments":{"href":"https://api.github.com/repos/openhab/openhab/issues/4586/comments"},"review_comments":{"href":"https://api.github.com/repos/openhab/openhab/pulls/4586/comments"},"review_comment":{"href":"https://api.github.com/repos/openhab/openhab/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/openhab/openhab/pulls/4586/commits"},"statuses":{"href":"https://api.github.com/repos/openhab/openhab/statuses/c8467349270b790fe1f69ba29a252bcfb2494ea4"}}}}
{"actor":{"display_login":"watou"}}