{"action":"created","comment":{"url":"https://api.github.com/repos/openhab/openhab2/pulls/comments/27255642","id":27255642,"diff_hunk":"@@ -0,0 +1,306 @@\n+/**\n+ * Copyright (c) 2014 openHAB UG (haftungsbeschraenkt) and others.\n+ * All rights reserved. This program and the accompanying materials\n+ * are made available under the terms of the Eclipse Public License v1.0\n+ * which accompanies this distribution, and is available at\n+ * http://www.eclipse.org/legal/epl-v10.html\n+ */\n+package org.openhab.binding.pulseaudio.handler;\n+\n+import static org.openhab.binding.pulseaudio.PulseaudioBindingConstants.*;\n+\n+import java.util.ArrayList;\n+import java.util.List;\n+import java.util.Set;\n+import java.util.concurrent.ScheduledFuture;\n+import java.util.concurrent.TimeUnit;\n+\n+import org.apache.commons.lang.StringUtils;\n+import org.eclipse.smarthome.config.core.Configuration;\n+import org.eclipse.smarthome.core.library.types.DecimalType;\n+import org.eclipse.smarthome.core.library.types.IncreaseDecreaseType;\n+import org.eclipse.smarthome.core.library.types.OnOffType;\n+import org.eclipse.smarthome.core.library.types.PercentType;\n+import org.eclipse.smarthome.core.library.types.StringType;\n+import org.eclipse.smarthome.core.thing.Bridge;\n+import org.eclipse.smarthome.core.thing.ChannelUID;\n+import org.eclipse.smarthome.core.thing.Thing;\n+import org.eclipse.smarthome.core.thing.ThingStatus;\n+import org.eclipse.smarthome.core.thing.ThingTypeUID;\n+import org.eclipse.smarthome.core.thing.ThingUID;\n+import org.eclipse.smarthome.core.thing.binding.BaseThingHandler;\n+import org.eclipse.smarthome.core.thing.binding.ThingHandler;\n+import org.eclipse.smarthome.core.types.Command;\n+import org.eclipse.smarthome.core.types.RefreshType;\n+import org.eclipse.smarthome.core.types.State;\n+import org.eclipse.smarthome.core.types.UnDefType;\n+import org.openhab.binding.pulseaudio.PulseaudioBindingConstants;\n+import org.openhab.binding.pulseaudio.internal.items.AbstractAudioDeviceConfig;\n+import org.openhab.binding.pulseaudio.internal.items.Sink;\n+import org.openhab.binding.pulseaudio.internal.items.SinkInput;\n+import org.slf4j.Logger;\n+import org.slf4j.LoggerFactory;\n+\n+import com.google.common.collect.Sets;\n+\n+/**\n+ * The {@link PulseaudioHandler} is responsible for handling commands, which are\n+ * sent to one of the channels.\n+ * \n+ * @author Tobias Bräutigam - Initial contribution\n+ */\n+public class PulseaudioHandler extends BaseThingHandler implements\n+\t\tDeviceStatusListener {\n+\n+\tpublic final static Set<ThingTypeUID> SUPPORTED_THING_TYPES_UIDS = Sets.newHashSet( \n+\t\t\tSINK_THING_TYPE, \n+\t\t\tCOMBINED_SINK_THING_TYPE,\n+\t\t\tSINK_INPUT_THING_TYPE,\n+\t\t\tSOURCE_THING_TYPE,\n+\t\t\tSOURCE_OUTPUT_THING_TYPE);\n+\t\t\t\n+\n+\tprivate int refresh = 60; // refresh every minute as default\n+\tScheduledFuture<?> refreshJob;\n+\n+\tprivate PulseaudioBridgeHandler bridgeHandler;\n+\n+\tprivate Logger logger = LoggerFactory.getLogger(PulseaudioHandler.class);\n+\n+\tprivate String name;\n+\n+\tpublic PulseaudioHandler(Thing thing) {\n+\t\tsuper(thing);\n+\t}\n+\n+\t/**\n+\t * {@inheritDoc}\n+\t */\n+\t@Override\n+\tpublic void initialize() {\n+\t\tConfiguration config = getThing().getConfiguration();\n+\t\tname = (String) config\n+\t\t\t\t.get(PulseaudioBindingConstants.DEVICE_PARAMETER_NAME);\n+\n+\t\t// until we get an update put the Thing offline\n+\t\tupdateStatus(ThingStatus.OFFLINE);\n+\t\tdeviceOnlineWatchdog();\n+\n+\t\t// Listen to Device\n+//\t\tPulseaudioBridgeHandler bridge = getPulseaudioBridgeHandler();\n+//\t\tif (bridge != null) {\n+//\t\t\tAbstractAudioDeviceConfig device = bridge.getDevice(name);\n+//\t\t\tif (device != null) {\n+//\n+//\t\t\t}\n+//\t\t}\n+\t}\n+\n+\t/*\n+\t * (non-Javadoc)\n+\t * \n+\t * @see org.eclipse.smarthome.core.thing.binding.BaseThingHandler#dispose()\n+\t */\n+\t@Override\n+\tpublic void dispose() {\n+\t\tif (refreshJob != null && !refreshJob.isCancelled()) {\n+\t\t\trefreshJob.cancel(true);\n+\t\t\trefreshJob = null;\n+\t\t}\n+\t\tupdateStatus(ThingStatus.OFFLINE);\n+\t\t// if (bridgeHandler != null)\n+\t\t// bridgeHandler.clearDeviceList();\n+\t\t// if (bridgeHandler != null)\n+\t\t// bridgeHandler.unregisterDeviceStatusListener(this);\n+\t\tbridgeHandler = null;\n+\t\tlogger.debug(\"Thing {} {} disposed.\", getThing().getUID(), name);\n+\t\tsuper.dispose();\n+\t}\n+\n+\tprivate void deviceOnlineWatchdog() {\n+\t\tRunnable runnable = new Runnable() {\n+\t\t\tpublic void run() {\n+\t\t\t\ttry {\n+\t\t\t\t\tPulseaudioBridgeHandler bridgeHandler = getPulseaudioBridgeHandler();\n+\t\t\t\t\tif (bridgeHandler != null) {\n+\t\t\t\t\t\tif (bridgeHandler.getDevice(name) == null) {\n+\t\t\t\t\t\t\tupdateStatus(ThingStatus.OFFLINE);\n+\t\t\t\t\t\t\tbridgeHandler = null;\n+\t\t\t\t\t\t} else {\n+\t\t\t\t\t\t\tupdateStatus(ThingStatus.ONLINE);\n+\t\t\t\t\t\t}\n+\n+\t\t\t\t\t} else {\n+\t\t\t\t\t\tlogger.debug(\n+\t\t\t\t\t\t\t\t\"Bridge for pulseaudio device {} not found.\",\n+\t\t\t\t\t\t\t\tname);\n+\t\t\t\t\t\tupdateStatus(ThingStatus.OFFLINE);\n+\t\t\t\t\t}\n+\n+\t\t\t\t} catch (Exception e) {\n+\t\t\t\t\tlogger.debug(\"Exception occurred during execution: {}\",\n+\t\t\t\t\t\t\te.getMessage(), e);\n+\t\t\t\t\tbridgeHandler = null;\n+\t\t\t\t}\n+\n+\t\t\t}\n+\t\t};\n+\n+\t\trefreshJob = scheduler.scheduleAtFixedRate(runnable, 0, refresh,\n+\t\t\t\tTimeUnit.SECONDS);\n+\t}\n+\n+\tprivate synchronized PulseaudioBridgeHandler getPulseaudioBridgeHandler() {\n+\n+\t\tif (this.bridgeHandler == null) {\n+\t\t\tBridge bridge = getBridge();\n+\t\t\tif (bridge == null) {\n+\t\t\t\tlogger.debug(\"Required bridge not defined for device {}.\", name);\n+\t\t\t\treturn null;\n+\t\t\t}\n+\t\t\tThingHandler handler = bridge.getHandler();\n+\t\t\tif (handler instanceof PulseaudioBridgeHandler) {\n+\t\t\t\tthis.bridgeHandler = (PulseaudioBridgeHandler) handler;\n+\t\t\t\tthis.bridgeHandler.registerDeviceStatusListener(this);\n+\t\t\t} else {\n+\t\t\t\tlogger.debug(\n+\t\t\t\t\t\t\"No available bridge handler found for device {} bridge {} .\",\n+\t\t\t\t\t\tname, bridge.getUID());\n+\t\t\t\treturn null;\n+\t\t\t}\n+\t\t}\n+\t\treturn this.bridgeHandler;\n+\t}\n+\n+\t@Override\n+\tpublic void handleCommand(ChannelUID channelUID, Command command) {\n+\t\tPulseaudioBridgeHandler bridge = getPulseaudioBridgeHandler();\n+\t\tif (bridge == null) {\n+\t\t\tlogger.warn(\"pulseaudio server bridge handler not found. Cannot handle command without bridge.\");\n+\t\t\treturn;\n+\t\t}\n+\t\tif (command instanceof RefreshType) {\n+\t\t\tbridge.handleCommand(channelUID, command);\n+\t\t\treturn;\n+\t\t}\n+\n+\t\tAbstractAudioDeviceConfig device = bridge.getDevice(name);\n+\t\tif (device == null) {\n+\t\t\tlogger.warn(\"device {} not found\", name);\n+\t\t\tupdateStatus(ThingStatus.OFFLINE);\n+\t\t\tbridgeHandler = null;\n+\t\t\treturn;\n+\t\t} else {\n+\t\t\tState updateState = UnDefType.UNDEF;\n+\t\t\tif (channelUID.getId().equals(\n+\t\t\t\t\tPulseaudioBindingConstants.VOLUME_CHANNEL)) {\n+\t\t\t\tif (command instanceof IncreaseDecreaseType) {\n+\t\t\t\t\t// refresh to get the current volume level\n+\t\t\t\t\tbridge.getClient().update();\n+\t\t\t\t\tdevice = bridge.getDevice(name);\n+\t\t\t\t\tint volume = device.getVolume();\n+\t\t\t\t\tif (command.equals(IncreaseDecreaseType.INCREASE))\n+\t\t\t\t\t\tvolume = Math.min(100, volume + 5);\n+\t\t\t\t\tif (command.equals(IncreaseDecreaseType.DECREASE))\n+\t\t\t\t\t\tvolume = Math.max(0, volume - 5);\n+\t\t\t\t\tbridge.getClient().setVolumePercent(device, volume);\n+\t\t\t\t\tupdateState = new PercentType(volume);\n+\t\t\t\t} else if (command instanceof PercentType) {\n+\t\t\t\t\tbridge.getClient().setVolumePercent(device,\n+\t\t\t\t\t\t\tInteger.valueOf(command.toString()));\n+\t\t\t\t\tupdateState = (PercentType) command;\n+\t\t\t\t} else if (command instanceof DecimalType) {\n+\t\t\t\t\t// set volume\n+\t\t\t\t\tbridge.getClient().setVolume(device,\n+\t\t\t\t\t\t\tInteger.valueOf(command.toString()));\n+\t\t\t\t\tupdateState = (DecimalType) command;\n+\t\t\t\t}\n+\t\t\t} else if (channelUID.getId().equals(\n+\t\t\t\t\tPulseaudioBindingConstants.MUTE_CHANNEL)) {\n+\t\t\t\tif (command instanceof OnOffType) {\n+\t\t\t\t\tbridge.getClient().setMute(device,\n+\t\t\t\t\t\t\tOnOffType.ON.equals(command));\n+\t\t\t\t\tupdateState = (OnOffType) command;\n+\t\t\t\t}\n+\t\t\t} else if (channelUID.getId().equals(\n+\t\t\t\t\tPulseaudioBindingConstants.SLAVES_CHANNEL)) {\n+\t\t\t\tif (device instanceof Sink && ((Sink)device).isCombinedSink()) {\n+\t\t\t\t\tif (command instanceof StringType) {\n+\t\t\t\t\t\tList<Sink> slaves = new ArrayList<Sink>();\n+\t\t\t\t\t\tfor (String slaveName : command.toString().split(\",\")) {\n+\t\t\t\t\t\t\tSink slave = bridge.getClient().getSink(slaveName.trim());\n+\t\t\t\t\t\t\tif (slave!=null) {\n+\t\t\t\t\t\t\t\tslaves.add(slave);\n+\t\t\t\t\t\t\t}\n+\t\t\t\t\t\t}\n+\t\t\t\t\t\tif (slaves.size()>0) {\n+\t\t\t\t\t\t\tbridge.getClient().setCombinedSinkSlaves(((Sink)device), slaves);\n+\t\t\t\t\t\t}\n+\t\t\t\t\t}\n+\t\t\t\t} else {\n+\t\t\t\t\tlogger.error(\"{} is no combined sink\",device);\n+\t\t\t\t}\n+\t\t\t} else if (channelUID.getId().equals(\n+\t\t\t\t\tPulseaudioBindingConstants.ROUTE_TO_SINK_CHANNEL)) {\n+\t\t\t\tif (device instanceof SinkInput) {\n+\t\t\t\t\tSink newSink = null;\n+\t\t\t\t\tif (command instanceof DecimalType) {\n+\t\t\t\t\t\tnewSink = bridge.getClient().getSink(((DecimalType)command).intValue());\n+\t\t\t\t\t} else {\n+\t\t\t\t\t\tnewSink = bridge.getClient().getSink(command.toString());\n+\t\t\t\t\t}\n+\t\t\t\t\tif (newSink!=null) {\n+\t\t\t\t\t\tlogger.debug(\"rerouting {} to {}\",device,newSink);\n+\t\t\t\t\t\tbridge.getClient().moveSinkInput(((SinkInput)device), newSink);\n+\t\t\t\t\t\tupdateState = new StringType(newSink.getPaName());\n+\t\t\t\t\t} else {\n+\t\t\t\t\t\tlogger.error(\"no sink {} found\",command.toString());\n+\t\t\t\t\t}\n+\t\t\t\t}\n+\t\t\t\t\n+\t\t\t}\n+\t\t\tlogger.info(\"updating \" + channelUID + \" to \" + updateState);","path":"addons/binding/org.openhab.binding.pulseaudio/src/main/java/org/openhab/binding/pulseaudio/handler/PulseaudioHandler.java","position":262,"original_position":262,"commit_id":"ade5ba9d571fa6bff059ed780c8fd576095c8c4d","original_commit_id":"ade5ba9d571fa6bff059ed780c8fd576095c8c4d","user":{"login":"kaikreuzer","id":3244965,"avatar_url":"https://avatars.githubusercontent.com/u/3244965?v=3","gravatar_id":"","url":"https://api.github.com/users/kaikreuzer","html_url":"https://github.com/kaikreuzer","followers_url":"https://api.github.com/users/kaikreuzer/followers","following_url":"https://api.github.com/users/kaikreuzer/following{/other_user}","gists_url":"https://api.github.com/users/kaikreuzer/gists{/gist_id}","starred_url":"https://api.github.com/users/kaikreuzer/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/kaikreuzer/subscriptions","organizations_url":"https://api.github.com/users/kaikreuzer/orgs","repos_url":"https://api.github.com/users/kaikreuzer/repos","events_url":"https://api.github.com/users/kaikreuzer/events{/privacy}","received_events_url":"https://api.github.com/users/kaikreuzer/received_events","type":"User","site_admin":false},"body":"reduce to trace","created_at":"2015-03-26T21:01:38Z","updated_at":"2015-03-26T21:01:38Z","html_url":"https://github.com/openhab/openhab2/pull/114#discussion_r27255642","pull_request_url":"https://api.github.com/repos/openhab/openhab2/pulls/114","_links":{"self":{"href":"https://api.github.com/repos/openhab/openhab2/pulls/comments/27255642"},"html":{"href":"https://github.com/openhab/openhab2/pull/114#discussion_r27255642"},"pull_request":{"href":"https://api.github.com/repos/openhab/openhab2/pulls/114"}}},"pull_request":{"url":"https://api.github.com/repos/openhab/openhab2/pulls/114","id":27592000,"html_url":"https://github.com/openhab/openhab2/pull/114","diff_url":"https://github.com/openhab/openhab2/pull/114.diff","patch_url":"https://github.com/openhab/openhab2/pull/114.patch","issue_url":"https://api.github.com/repos/openhab/openhab2/issues/114","number":114,"state":"open","locked":false,"title":"initial contribution of the new pulseaudio binding","user":{"login":"peuter","id":5507035,"avatar_url":"https://avatars.githubusercontent.com/u/5507035?v=3","gravatar_id":"","url":"https://api.github.com/users/peuter","html_url":"https://github.com/peuter","followers_url":"https://api.github.com/users/peuter/followers","following_url":"https://api.github.com/users/peuter/following{/other_user}","gists_url":"https://api.github.com/users/peuter/gists{/gist_id}","starred_url":"https://api.github.com/users/peuter/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/peuter/subscriptions","organizations_url":"https://api.github.com/users/peuter/orgs","repos_url":"https://api.github.com/users/peuter/repos","events_url":"https://api.github.com/users/peuter/events{/privacy}","received_events_url":"https://api.github.com/users/peuter/received_events","type":"User","site_admin":false},"body":"2.0 ready including discovery, required the new mDNS discovery feature, which has to be merged in ESH first:\r\nhttps://github.com/eclipse/smarthome/pull/158\r\n","created_at":"2015-01-19T08:52:21Z","updated_at":"2015-03-26T21:01:38Z","closed_at":null,"merged_at":null,"merge_commit_sha":"4a43e31580efafe7f0645f8da6309c2abe732fc5","assignee":{"login":"kaikreuzer","id":3244965,"avatar_url":"https://avatars.githubusercontent.com/u/3244965?v=3","gravatar_id":"","url":"https://api.github.com/users/kaikreuzer","html_url":"https://github.com/kaikreuzer","followers_url":"https://api.github.com/users/kaikreuzer/followers","following_url":"https://api.github.com/users/kaikreuzer/following{/other_user}","gists_url":"https://api.github.com/users/kaikreuzer/gists{/gist_id}","starred_url":"https://api.github.com/users/kaikreuzer/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/kaikreuzer/subscriptions","organizations_url":"https://api.github.com/users/kaikreuzer/orgs","repos_url":"https://api.github.com/users/kaikreuzer/repos","events_url":"https://api.github.com/users/kaikreuzer/events{/privacy}","received_events_url":"https://api.github.com/users/kaikreuzer/received_events","type":"User","site_admin":false},"milestone":null,"commits_url":"https://api.github.com/repos/openhab/openhab2/pulls/114/commits","review_comments_url":"https://api.github.com/repos/openhab/openhab2/pulls/114/comments","review_comment_url":"https://api.github.com/repos/openhab/openhab2/pulls/comments{/number}","comments_url":"https://api.github.com/repos/openhab/openhab2/issues/114/comments","statuses_url":"https://api.github.com/repos/openhab/openhab2/statuses/ade5ba9d571fa6bff059ed780c8fd576095c8c4d","head":{"label":"peuter:pulseaudio","ref":"pulseaudio","sha":"ade5ba9d571fa6bff059ed780c8fd576095c8c4d","user":{"login":"peuter","id":5507035,"avatar_url":"https://avatars.githubusercontent.com/u/5507035?v=3","gravatar_id":"","url":"https://api.github.com/users/peuter","html_url":"https://github.com/peuter","followers_url":"https://api.github.com/users/peuter/followers","following_url":"https://api.github.com/users/peuter/following{/other_user}","gists_url":"https://api.github.com/users/peuter/gists{/gist_id}","starred_url":"https://api.github.com/users/peuter/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/peuter/subscriptions","organizations_url":"https://api.github.com/users/peuter/orgs","repos_url":"https://api.github.com/users/peuter/repos","events_url":"https://api.github.com/users/peuter/events{/privacy}","received_events_url":"https://api.github.com/users/peuter/received_events","type":"User","site_admin":false},"repo":{"id":27497639,"name":"openhab2","full_name":"peuter/openhab2","owner":{"login":"peuter","id":5507035,"avatar_url":"https://avatars.githubusercontent.com/u/5507035?v=3","gravatar_id":"","url":"https://api.github.com/users/peuter","html_url":"https://github.com/peuter","followers_url":"https://api.github.com/users/peuter/followers","following_url":"https://api.github.com/users/peuter/following{/other_user}","gists_url":"https://api.github.com/users/peuter/gists{/gist_id}","starred_url":"https://api.github.com/users/peuter/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/peuter/subscriptions","organizations_url":"https://api.github.com/users/peuter/orgs","repos_url":"https://api.github.com/users/peuter/repos","events_url":"https://api.github.com/users/peuter/events{/privacy}","received_events_url":"https://api.github.com/users/peuter/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/peuter/openhab2","description":"The next-generation open Home Automation Bus (openHAB)","fork":true,"url":"https://api.github.com/repos/peuter/openhab2","forks_url":"https://api.github.com/repos/peuter/openhab2/forks","keys_url":"https://api.github.com/repos/peuter/openhab2/keys{/key_id}","collaborators_url":"https://api.github.com/repos/peuter/openhab2/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/peuter/openhab2/teams","hooks_url":"https://api.github.com/repos/peuter/openhab2/hooks","issue_events_url":"https://api.github.com/repos/peuter/openhab2/issues/events{/number}","events_url":"https://api.github.com/repos/peuter/openhab2/events","assignees_url":"https://api.github.com/repos/peuter/openhab2/assignees{/user}","branches_url":"https://api.github.com/repos/peuter/openhab2/branches{/branch}","tags_url":"https://api.github.com/repos/peuter/openhab2/tags","blobs_url":"https://api.github.com/repos/peuter/openhab2/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/peuter/openhab2/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/peuter/openhab2/git/refs{/sha}","trees_url":"https://api.github.com/repos/peuter/openhab2/git/trees{/sha}","statuses_url":"https://api.github.com/repos/peuter/openhab2/statuses/{sha}","languages_url":"https://api.github.com/repos/peuter/openhab2/languages","stargazers_url":"https://api.github.com/repos/peuter/openhab2/stargazers","contributors_url":"https://api.github.com/repos/peuter/openhab2/contributors","subscribers_url":"https://api.github.com/repos/peuter/openhab2/subscribers","subscription_url":"https://api.github.com/repos/peuter/openhab2/subscription","commits_url":"https://api.github.com/repos/peuter/openhab2/commits{/sha}","git_commits_url":"https://api.github.com/repos/peuter/openhab2/git/commits{/sha}","comments_url":"https://api.github.com/repos/peuter/openhab2/comments{/number}","issue_comment_url":"https://api.github.com/repos/peuter/openhab2/issues/comments{/number}","contents_url":"https://api.github.com/repos/peuter/openhab2/contents/{+path}","compare_url":"https://api.github.com/repos/peuter/openhab2/compare/{base}...{head}","merges_url":"https://api.github.com/repos/peuter/openhab2/merges","archive_url":"https://api.github.com/repos/peuter/openhab2/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/peuter/openhab2/downloads","issues_url":"https://api.github.com/repos/peuter/openhab2/issues{/number}","pulls_url":"https://api.github.com/repos/peuter/openhab2/pulls{/number}","milestones_url":"https://api.github.com/repos/peuter/openhab2/milestones{/number}","notifications_url":"https://api.github.com/repos/peuter/openhab2/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/peuter/openhab2/labels{/name}","releases_url":"https://api.github.com/repos/peuter/openhab2/releases{/id}","created_at":"2014-12-03T16:59:05Z","updated_at":"2015-03-19T17:54:43Z","pushed_at":"2015-03-26T17:15:25Z","git_url":"git://github.com/peuter/openhab2.git","ssh_url":"git@github.com:peuter/openhab2.git","clone_url":"https://github.com/peuter/openhab2.git","svn_url":"https://github.com/peuter/openhab2","homepage":null,"size":12788,"stargazers_count":0,"watchers_count":0,"language":"Java","has_issues":false,"has_downloads":true,"has_wiki":false,"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":"deffae890cbaff15b240dd06b0474a5aeb3105b3","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":19753195,"name":"openhab2","full_name":"openhab/openhab2","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/openhab2","description":"The next-generation open Home Automation Bus (openHAB)","fork":false,"url":"https://api.github.com/repos/openhab/openhab2","forks_url":"https://api.github.com/repos/openhab/openhab2/forks","keys_url":"https://api.github.com/repos/openhab/openhab2/keys{/key_id}","collaborators_url":"https://api.github.com/repos/openhab/openhab2/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/openhab/openhab2/teams","hooks_url":"https://api.github.com/repos/openhab/openhab2/hooks","issue_events_url":"https://api.github.com/repos/openhab/openhab2/issues/events{/number}","events_url":"https://api.github.com/repos/openhab/openhab2/events","assignees_url":"https://api.github.com/repos/openhab/openhab2/assignees{/user}","branches_url":"https://api.github.com/repos/openhab/openhab2/branches{/branch}","tags_url":"https://api.github.com/repos/openhab/openhab2/tags","blobs_url":"https://api.github.com/repos/openhab/openhab2/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/openhab/openhab2/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/openhab/openhab2/git/refs{/sha}","trees_url":"https://api.github.com/repos/openhab/openhab2/git/trees{/sha}","statuses_url":"https://api.github.com/repos/openhab/openhab2/statuses/{sha}","languages_url":"https://api.github.com/repos/openhab/openhab2/languages","stargazers_url":"https://api.github.com/repos/openhab/openhab2/stargazers","contributors_url":"https://api.github.com/repos/openhab/openhab2/contributors","subscribers_url":"https://api.github.com/repos/openhab/openhab2/subscribers","subscription_url":"https://api.github.com/repos/openhab/openhab2/subscription","commits_url":"https://api.github.com/repos/openhab/openhab2/commits{/sha}","git_commits_url":"https://api.github.com/repos/openhab/openhab2/git/commits{/sha}","comments_url":"https://api.github.com/repos/openhab/openhab2/comments{/number}","issue_comment_url":"https://api.github.com/repos/openhab/openhab2/issues/comments{/number}","contents_url":"https://api.github.com/repos/openhab/openhab2/contents/{+path}","compare_url":"https://api.github.com/repos/openhab/openhab2/compare/{base}...{head}","merges_url":"https://api.github.com/repos/openhab/openhab2/merges","archive_url":"https://api.github.com/repos/openhab/openhab2/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/openhab/openhab2/downloads","issues_url":"https://api.github.com/repos/openhab/openhab2/issues{/number}","pulls_url":"https://api.github.com/repos/openhab/openhab2/pulls{/number}","milestones_url":"https://api.github.com/repos/openhab/openhab2/milestones{/number}","notifications_url":"https://api.github.com/repos/openhab/openhab2/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/openhab/openhab2/labels{/name}","releases_url":"https://api.github.com/repos/openhab/openhab2/releases{/id}","created_at":"2014-05-13T19:41:58Z","updated_at":"2015-03-26T19:47:19Z","pushed_at":"2015-03-26T19:47:19Z","git_url":"git://github.com/openhab/openhab2.git","ssh_url":"git@github.com:openhab/openhab2.git","clone_url":"https://github.com/openhab/openhab2.git","svn_url":"https://github.com/openhab/openhab2","homepage":null,"size":15662,"stargazers_count":120,"watchers_count":120,"language":"Java","has_issues":true,"has_downloads":true,"has_wiki":false,"has_pages":false,"forks_count":220,"mirror_url":null,"open_issues_count":39,"forks":220,"open_issues":39,"watchers":120,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/openhab/openhab2/pulls/114"},"html":{"href":"https://github.com/openhab/openhab2/pull/114"},"issue":{"href":"https://api.github.com/repos/openhab/openhab2/issues/114"},"comments":{"href":"https://api.github.com/repos/openhab/openhab2/issues/114/comments"},"review_comments":{"href":"https://api.github.com/repos/openhab/openhab2/pulls/114/comments"},"review_comment":{"href":"https://api.github.com/repos/openhab/openhab2/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/openhab/openhab2/pulls/114/commits"},"statuses":{"href":"https://api.github.com/repos/openhab/openhab2/statuses/ade5ba9d571fa6bff059ed780c8fd576095c8c4d"}}}}