{"action":"created","comment":{"url":"https://api.github.com/repos/pcdshub/pcdsdevices/pulls/comments/180587153","pull_request_review_id":111034336,"id":180587153,"diff_hunk":"@@ -0,0 +1,169 @@\n+import time\n+import logging\n+from functools import partial\n+\n+from ophyd import Device, EpicsSignal, EpicsSignalRO, Component as Cpt\n+from ophyd.status import DeviceStatus, SubscriptionStatus\n+from ophyd.utils.epics_pvs import raise_if_disconnected\n+\n+\n+logger = logging.getLogger(__name__)\n+\n+\n+class EventSequencer(Device):\n+    \"\"\"\n+    Event Sequencer\n+\n+    The LCLS Event Sequencer implemented as an Flyer; i.e it has the methods\n+    :meth:`.kickoff`, :meth:`.complete` and :meth:`.collect`. This allows the\n+    EventSequencer to be used succinctly with the `fly_during_wrapper` and\n+    associated preprocessor.\n+\n+    Parameters\n+    ----------\n+    prefix: str\n+        Base prefix of the EventSequencer\n+\n+    name : str\n+        Name of Event Sequencer object\n+\n+    Examples\n+    --------\n+    Run the EventSequencer throughout my scan\n+\n+    .. code::\n+\n+        fly_during_wrapper(scan([det], motor, ...), [sequencer])\n+\n+    Run the EventSequencer at each step in my scan, after the completing the\n+    motor move.\n+\n+    .. code::\n+\n+        def step_then_sequence(detectors, step, pos_cache)\n+            yield from one_nd_step(detectors, step, pos_cache)\n+            yield from kickoff(sequencer)\n+            yield from complete(sequencer)  # Waits for sequence to complete if\n+                                            # not in \"Run Forever\" mode\n+\n+        scan([det], motor, ..., per_step=step_then_sequence)\n+    \"\"\"\n+    play_control = Cpt(EpicsSignal, ':PLYCTL')\n+    sequence_length = Cpt(EpicsSignal, ':LEN')\n+    current_step = Cpt(EpicsSignal, ':CURSTP')\n+    play_count = Cpt(EpicsSignal, ':PLYCNT')\n+    play_status = Cpt(EpicsSignalRO, ':PLSTAT', auto_monitor=True)\n+    play_mode = Cpt(EpicsSignal, ':PLYMOD')\n+\n+    _default_read_attrs = ['play_status']\n+    _default_configuration_attrs = ['play_mode', 'sequence_length']\n+\n+    def __init__(self, prefix, *, name=None,  **kwargs):\n+        # Device initialization\n+        super().__init__(prefix, name=name, **kwargs)\n+        # Data caches\n+        self._steps = list()\n+        self._iterations = list()\n+\n+    @raise_if_disconnected\n+    def kickoff(self):\n+        \"\"\"\n+        Start the EventSequencer\n+\n+        Returns\n+        -------\n+        status : SubscriptionStatus\n+            Status indicating whether or not the EventSequencer has started\n+        \"\"\"\n+        # Clear cached data from prior runs\n+        self._steps.clear()\n+        self._iterations.clear()\n+        # Start the sequencer\n+        self.play_control.set(1)\n+\n+        # Subscribe to changes in the play step and iteration\n+        def add_event(cache, timestamp=None, value=None, **kwargs):\n+            cache.append((timestamp, value))\n+\n+        self.current_step.subscribe(partial(add_event, self._steps))\n+        self.play_count.subscribe(partial(add_event, self._iterations))\n+\n+        # Create our status\n+        def done(*args, value=None, old_value=None, **kwargs):\n+            return value == 2 and old_value == 0\n+        # Create our status object\n+        return SubscriptionStatus(self.play_status, done, run=True)\n+\n+    def complete(self):\n+        \"\"\"\n+        Complete the EventSequencer's current sequence\n+\n+        The result of this method varies on the mode that the EventSequencer is\n+        configured. If the EventSequencer is either set to \"Run Once\" or \"Run N\n+        Times\" this method allows the current sequence to complete and returns\n+        a status object that indicates a successful completion. However, this\n+        mode of operation does not make sense if the EventSequencer is in\n+        \"Run Forever\" mode. In this case, the EventSequencer is stopped\n+        immediately and a completed status object is returned.\n+\n+        Returns\n+        -------\n+        status: DeviceStatus or SubscriptionStatus\n+            Status indicating completion of sequence\n+\n+        Note\n+        ----\n+        If you want to stop the sequence from running regardless of\n+        configuration use the :meth:`.stop` command.\n+\n+        \"\"\"\n+        # Clear subscriptions\n+        def clear_subs(**kwargs):\n+            self.current_step.unsubscribe_all()\n+            self.play_count.unsubscribe_all()\n+\n+        # If we are running forever we can stop whenever\n+        if self.play_mode.get() == 2:\n+            self.stop()\n+            clear_subs()\n+            return DeviceStatus(self, done=True, success=True)\n+\n+        # Otherwise we should wait for the sequencer to end\n+        def done(*args, value=None, old_value=None, **kwargs):\n+            return value == 0 and old_value == 2\n+\n+        # Create a SubscriptionStatus\n+        st = SubscriptionStatus(self.play_status, done, run=True)\n+        st.add_callback(clear_subs)\n+        return st\n+\n+    def collect(self):\n+        \"\"\"\n+        Gather information about the state of the Sequencer\n+\n+        During :meth:`.kickoff`, a monitor is started on the ``current_step``\n+        and ``play_count`` signals. The timestamps and values of these signals\n+        are stored internally and can be added back into the data stream\n+        asynchronously by calling this method.\n+        \"\"\"\n+        # Create partial event document\n+        event = {'time': time.time(), 'timestamps': dict(), 'data': dict()}\n+        for sig, cache in zip((self.current_step, self.play_count),\n+                              (self._steps, self._iterations)):\n+            event['timestamps'][sig.name] = [evt[0] for evt in cache]\n+            event['data'][sig.name] = [evt[1] for evt in cache]\n+        # Clear caches\n+        self._steps.clear()\n+        self._iterations.clear()\n+        yield event\n+\n+    def describe_collect(self):\n+        \"\"\"Describe the collection information\"\"\"\n+        dd = dict()\n+        dd.update(self.play_count.describe())\n+        dd.update(self.current_step.describe())\n+        return {'sequence': dd}\n+\n+    def stop(self):\n+        \"\"\"Stop the EventSequencer\"\"\"\n+        self.play_control.put(0)","path":"pcdsdevices/sequencer.py","position":null,"original_position":169,"commit_id":"66c9950496d43d7ce19b09e3766019b33dbe4ff8","original_commit_id":"434b27b9a3024166d973bd05d1a0946bd37a4d42","user":{"login":"teddyrendahl","id":25753048,"avatar_url":"https://avatars3.githubusercontent.com/u/25753048?v=4","gravatar_id":"","url":"https://api.github.com/users/teddyrendahl","html_url":"https://github.com/teddyrendahl","followers_url":"https://api.github.com/users/teddyrendahl/followers","following_url":"https://api.github.com/users/teddyrendahl/following{/other_user}","gists_url":"https://api.github.com/users/teddyrendahl/gists{/gist_id}","starred_url":"https://api.github.com/users/teddyrendahl/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/teddyrendahl/subscriptions","organizations_url":"https://api.github.com/users/teddyrendahl/orgs","repos_url":"https://api.github.com/users/teddyrendahl/repos","events_url":"https://api.github.com/users/teddyrendahl/events{/privacy}","received_events_url":"https://api.github.com/users/teddyrendahl/received_events","type":"User","site_admin":false},"body":"Disagree. `stop_movable_objects` called on `pause` only stops objects that received a `set` command.\r\n\r\nhttps://github.com/NSLS-II/bluesky/blob/a64a205f1b7f090c99ab74074e913ce444c56841/bluesky/run_engine.py#L985\r\n\r\n","created_at":"2018-04-10T22:33:20Z","updated_at":"2018-04-10T22:33:20Z","html_url":"https://github.com/pcdshub/pcdsdevices/pull/196#discussion_r180587153","pull_request_url":"https://api.github.com/repos/pcdshub/pcdsdevices/pulls/196","author_association":"CONTRIBUTOR","_links":{"self":{"href":"https://api.github.com/repos/pcdshub/pcdsdevices/pulls/comments/180587153"},"html":{"href":"https://github.com/pcdshub/pcdsdevices/pull/196#discussion_r180587153"},"pull_request":{"href":"https://api.github.com/repos/pcdshub/pcdsdevices/pulls/196"}},"in_reply_to_id":180573451},"pull_request":{"url":"https://api.github.com/repos/pcdshub/pcdsdevices/pulls/196","id":180703431,"html_url":"https://github.com/pcdshub/pcdsdevices/pull/196","diff_url":"https://github.com/pcdshub/pcdsdevices/pull/196.diff","patch_url":"https://github.com/pcdshub/pcdsdevices/pull/196.patch","issue_url":"https://api.github.com/repos/pcdshub/pcdsdevices/issues/196","number":196,"state":"open","locked":false,"title":"EventSequencer","user":{"login":"teddyrendahl","id":25753048,"avatar_url":"https://avatars3.githubusercontent.com/u/25753048?v=4","gravatar_id":"","url":"https://api.github.com/users/teddyrendahl","html_url":"https://github.com/teddyrendahl","followers_url":"https://api.github.com/users/teddyrendahl/followers","following_url":"https://api.github.com/users/teddyrendahl/following{/other_user}","gists_url":"https://api.github.com/users/teddyrendahl/gists{/gist_id}","starred_url":"https://api.github.com/users/teddyrendahl/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/teddyrendahl/subscriptions","organizations_url":"https://api.github.com/users/teddyrendahl/orgs","repos_url":"https://api.github.com/users/teddyrendahl/repos","events_url":"https://api.github.com/users/teddyrendahl/events{/privacy}","received_events_url":"https://api.github.com/users/teddyrendahl/received_events","type":"User","site_admin":false},"body":"<!--- Provide a general summary of your changes in the Title above -->\r\n## Description\r\n<!--- Describe your changes in detail -->\r\nA basic `EventSequencer` object. \r\n\r\nThis handles **only** starting and stopping the `EventSequencer` in the various modes of operation. Actually configuring what the sequence loaded is should be discussed outside of this PR. \r\n\r\nI suspect the main controversy will be the fact that this is a `bluesky` flyer. I decided to go this route because the `set` method does not make much sense. In reality most of the time you want to start and stop the Event Sequencer as two entirely separate actions.  This works especially nicely if you just want to run the sequencer the entire time you are scanning:\r\n\r\n```python\r\nfly_during_wrapper(my_scan, [sequencer])\r\n```\r\n\r\nI do agree that when you want to keep starting and stopping the sequencer during a scan it is a little more awkward, but I don't think the `set` and `wait` syntax really makes much more sense. I like the granularity of this. It is clear exactly when I want to start the sequence, and exactly when I want to wait for my sequence to complete.\r\n```python\r\ndef step_then_sequence(detectors, step, pos_cache):\r\n   yield from one_nd_step(detectors, step, pos_cache)\r\n   yield from kickoff(sequencer)\r\n   yield from complete(sequencer, wait=True)\r\n\r\nscan([det], motor, ..., per_step=step_then_sequence)\r\n```\r\n## Motivation and Context\r\n<!--- Why is this change required? What problem does it solve? -->\r\n<!--- If it fixes an open issue, please link to the issue here. -->\r\nCloses #195 \r\n\r\n## How Has This Been Tested?\r\n<!--- Please describe in detail how you tested your changes. -->\r\n<!--- Include details of your testing environment, and the tests you ran to -->\r\n<!--- see how your change affects other areas of the code, etc. -->\r\n* Added to test suite a series of methods that run the `EventSequencer` in a `bluesky` plan as well as some more in-depth tests on specific methods\r\n* Tested with the CXI EventSequencer `R3.8.0`\r\n\r\n## Where Has This Been Documented?\r\n<!--  Include where the changes made have been documented. -->\r\n<!--  This can simply be  a comment in the code or updating a docstring -->\r\nAdded to `device_types` table. Included some sample use cases\r\n","created_at":"2018-04-10T19:25:16Z","updated_at":"2018-04-10T22:33:20Z","closed_at":null,"merged_at":null,"merge_commit_sha":"f637f09928a653e851dc48cbd1315ba1be56cb2d","assignee":null,"assignees":[],"requested_reviewers":[{"login":"apra93","id":10396832,"avatar_url":"https://avatars1.githubusercontent.com/u/10396832?v=4","gravatar_id":"","url":"https://api.github.com/users/apra93","html_url":"https://github.com/apra93","followers_url":"https://api.github.com/users/apra93/followers","following_url":"https://api.github.com/users/apra93/following{/other_user}","gists_url":"https://api.github.com/users/apra93/gists{/gist_id}","starred_url":"https://api.github.com/users/apra93/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/apra93/subscriptions","organizations_url":"https://api.github.com/users/apra93/orgs","repos_url":"https://api.github.com/users/apra93/repos","events_url":"https://api.github.com/users/apra93/events{/privacy}","received_events_url":"https://api.github.com/users/apra93/received_events","type":"User","site_admin":false},{"login":"n-wbrown","id":20483116,"avatar_url":"https://avatars3.githubusercontent.com/u/20483116?v=4","gravatar_id":"","url":"https://api.github.com/users/n-wbrown","html_url":"https://github.com/n-wbrown","followers_url":"https://api.github.com/users/n-wbrown/followers","following_url":"https://api.github.com/users/n-wbrown/following{/other_user}","gists_url":"https://api.github.com/users/n-wbrown/gists{/gist_id}","starred_url":"https://api.github.com/users/n-wbrown/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/n-wbrown/subscriptions","organizations_url":"https://api.github.com/users/n-wbrown/orgs","repos_url":"https://api.github.com/users/n-wbrown/repos","events_url":"https://api.github.com/users/n-wbrown/events{/privacy}","received_events_url":"https://api.github.com/users/n-wbrown/received_events","type":"User","site_admin":false}],"requested_teams":[],"labels":[],"milestone":null,"commits_url":"https://api.github.com/repos/pcdshub/pcdsdevices/pulls/196/commits","review_comments_url":"https://api.github.com/repos/pcdshub/pcdsdevices/pulls/196/comments","review_comment_url":"https://api.github.com/repos/pcdshub/pcdsdevices/pulls/comments{/number}","comments_url":"https://api.github.com/repos/pcdshub/pcdsdevices/issues/196/comments","statuses_url":"https://api.github.com/repos/pcdshub/pcdsdevices/statuses/66c9950496d43d7ce19b09e3766019b33dbe4ff8","head":{"label":"teddyrendahl:seq","ref":"seq","sha":"66c9950496d43d7ce19b09e3766019b33dbe4ff8","user":{"login":"teddyrendahl","id":25753048,"avatar_url":"https://avatars3.githubusercontent.com/u/25753048?v=4","gravatar_id":"","url":"https://api.github.com/users/teddyrendahl","html_url":"https://github.com/teddyrendahl","followers_url":"https://api.github.com/users/teddyrendahl/followers","following_url":"https://api.github.com/users/teddyrendahl/following{/other_user}","gists_url":"https://api.github.com/users/teddyrendahl/gists{/gist_id}","starred_url":"https://api.github.com/users/teddyrendahl/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/teddyrendahl/subscriptions","organizations_url":"https://api.github.com/users/teddyrendahl/orgs","repos_url":"https://api.github.com/users/teddyrendahl/repos","events_url":"https://api.github.com/users/teddyrendahl/events{/privacy}","received_events_url":"https://api.github.com/users/teddyrendahl/received_events","type":"User","site_admin":false},"repo":{"id":118982204,"name":"pcdsdevices","full_name":"teddyrendahl/pcdsdevices","owner":{"login":"teddyrendahl","id":25753048,"avatar_url":"https://avatars3.githubusercontent.com/u/25753048?v=4","gravatar_id":"","url":"https://api.github.com/users/teddyrendahl","html_url":"https://github.com/teddyrendahl","followers_url":"https://api.github.com/users/teddyrendahl/followers","following_url":"https://api.github.com/users/teddyrendahl/following{/other_user}","gists_url":"https://api.github.com/users/teddyrendahl/gists{/gist_id}","starred_url":"https://api.github.com/users/teddyrendahl/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/teddyrendahl/subscriptions","organizations_url":"https://api.github.com/users/teddyrendahl/orgs","repos_url":"https://api.github.com/users/teddyrendahl/repos","events_url":"https://api.github.com/users/teddyrendahl/events{/privacy}","received_events_url":"https://api.github.com/users/teddyrendahl/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/teddyrendahl/pcdsdevices","description":"Collection of Ophyd device subclasses for IOCs unique to LCLS PCDS.","fork":true,"url":"https://api.github.com/repos/teddyrendahl/pcdsdevices","forks_url":"https://api.github.com/repos/teddyrendahl/pcdsdevices/forks","keys_url":"https://api.github.com/repos/teddyrendahl/pcdsdevices/keys{/key_id}","collaborators_url":"https://api.github.com/repos/teddyrendahl/pcdsdevices/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/teddyrendahl/pcdsdevices/teams","hooks_url":"https://api.github.com/repos/teddyrendahl/pcdsdevices/hooks","issue_events_url":"https://api.github.com/repos/teddyrendahl/pcdsdevices/issues/events{/number}","events_url":"https://api.github.com/repos/teddyrendahl/pcdsdevices/events","assignees_url":"https://api.github.com/repos/teddyrendahl/pcdsdevices/assignees{/user}","branches_url":"https://api.github.com/repos/teddyrendahl/pcdsdevices/branches{/branch}","tags_url":"https://api.github.com/repos/teddyrendahl/pcdsdevices/tags","blobs_url":"https://api.github.com/repos/teddyrendahl/pcdsdevices/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/teddyrendahl/pcdsdevices/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/teddyrendahl/pcdsdevices/git/refs{/sha}","trees_url":"https://api.github.com/repos/teddyrendahl/pcdsdevices/git/trees{/sha}","statuses_url":"https://api.github.com/repos/teddyrendahl/pcdsdevices/statuses/{sha}","languages_url":"https://api.github.com/repos/teddyrendahl/pcdsdevices/languages","stargazers_url":"https://api.github.com/repos/teddyrendahl/pcdsdevices/stargazers","contributors_url":"https://api.github.com/repos/teddyrendahl/pcdsdevices/contributors","subscribers_url":"https://api.github.com/repos/teddyrendahl/pcdsdevices/subscribers","subscription_url":"https://api.github.com/repos/teddyrendahl/pcdsdevices/subscription","commits_url":"https://api.github.com/repos/teddyrendahl/pcdsdevices/commits{/sha}","git_commits_url":"https://api.github.com/repos/teddyrendahl/pcdsdevices/git/commits{/sha}","comments_url":"https://api.github.com/repos/teddyrendahl/pcdsdevices/comments{/number}","issue_comment_url":"https://api.github.com/repos/teddyrendahl/pcdsdevices/issues/comments{/number}","contents_url":"https://api.github.com/repos/teddyrendahl/pcdsdevices/contents/{+path}","compare_url":"https://api.github.com/repos/teddyrendahl/pcdsdevices/compare/{base}...{head}","merges_url":"https://api.github.com/repos/teddyrendahl/pcdsdevices/merges","archive_url":"https://api.github.com/repos/teddyrendahl/pcdsdevices/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/teddyrendahl/pcdsdevices/downloads","issues_url":"https://api.github.com/repos/teddyrendahl/pcdsdevices/issues{/number}","pulls_url":"https://api.github.com/repos/teddyrendahl/pcdsdevices/pulls{/number}","milestones_url":"https://api.github.com/repos/teddyrendahl/pcdsdevices/milestones{/number}","notifications_url":"https://api.github.com/repos/teddyrendahl/pcdsdevices/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/teddyrendahl/pcdsdevices/labels{/name}","releases_url":"https://api.github.com/repos/teddyrendahl/pcdsdevices/releases{/id}","deployments_url":"https://api.github.com/repos/teddyrendahl/pcdsdevices/deployments","created_at":"2018-01-26T00:01:35Z","updated_at":"2018-04-10T19:40:34Z","pushed_at":"2018-04-10T22:29:35Z","git_url":"git://github.com/teddyrendahl/pcdsdevices.git","ssh_url":"git@github.com:teddyrendahl/pcdsdevices.git","clone_url":"https://github.com/teddyrendahl/pcdsdevices.git","svn_url":"https://github.com/teddyrendahl/pcdsdevices","homepage":null,"size":983,"stargazers_count":0,"watchers_count":0,"language":"Python","has_issues":false,"has_projects":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":0,"mirror_url":null,"archived":false,"open_issues_count":0,"license":{"key":"other","name":"Other","spdx_id":null,"url":null},"forks":0,"open_issues":0,"watchers":0,"default_branch":"master"}},"base":{"label":"pcdshub:master","ref":"master","sha":"30043c282b36d566ca510fd0cbfa0fcc7f2e9087","user":{"login":"pcdshub","id":31903189,"avatar_url":"https://avatars1.githubusercontent.com/u/31903189?v=4","gravatar_id":"","url":"https://api.github.com/users/pcdshub","html_url":"https://github.com/pcdshub","followers_url":"https://api.github.com/users/pcdshub/followers","following_url":"https://api.github.com/users/pcdshub/following{/other_user}","gists_url":"https://api.github.com/users/pcdshub/gists{/gist_id}","starred_url":"https://api.github.com/users/pcdshub/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/pcdshub/subscriptions","organizations_url":"https://api.github.com/users/pcdshub/orgs","repos_url":"https://api.github.com/users/pcdshub/repos","events_url":"https://api.github.com/users/pcdshub/events{/privacy}","received_events_url":"https://api.github.com/users/pcdshub/received_events","type":"Organization","site_admin":false},"repo":{"id":84994316,"name":"pcdsdevices","full_name":"pcdshub/pcdsdevices","owner":{"login":"pcdshub","id":31903189,"avatar_url":"https://avatars1.githubusercontent.com/u/31903189?v=4","gravatar_id":"","url":"https://api.github.com/users/pcdshub","html_url":"https://github.com/pcdshub","followers_url":"https://api.github.com/users/pcdshub/followers","following_url":"https://api.github.com/users/pcdshub/following{/other_user}","gists_url":"https://api.github.com/users/pcdshub/gists{/gist_id}","starred_url":"https://api.github.com/users/pcdshub/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/pcdshub/subscriptions","organizations_url":"https://api.github.com/users/pcdshub/orgs","repos_url":"https://api.github.com/users/pcdshub/repos","events_url":"https://api.github.com/users/pcdshub/events{/privacy}","received_events_url":"https://api.github.com/users/pcdshub/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/pcdshub/pcdsdevices","description":"Collection of Ophyd device subclasses for IOCs unique to LCLS PCDS.","fork":false,"url":"https://api.github.com/repos/pcdshub/pcdsdevices","forks_url":"https://api.github.com/repos/pcdshub/pcdsdevices/forks","keys_url":"https://api.github.com/repos/pcdshub/pcdsdevices/keys{/key_id}","collaborators_url":"https://api.github.com/repos/pcdshub/pcdsdevices/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/pcdshub/pcdsdevices/teams","hooks_url":"https://api.github.com/repos/pcdshub/pcdsdevices/hooks","issue_events_url":"https://api.github.com/repos/pcdshub/pcdsdevices/issues/events{/number}","events_url":"https://api.github.com/repos/pcdshub/pcdsdevices/events","assignees_url":"https://api.github.com/repos/pcdshub/pcdsdevices/assignees{/user}","branches_url":"https://api.github.com/repos/pcdshub/pcdsdevices/branches{/branch}","tags_url":"https://api.github.com/repos/pcdshub/pcdsdevices/tags","blobs_url":"https://api.github.com/repos/pcdshub/pcdsdevices/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/pcdshub/pcdsdevices/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/pcdshub/pcdsdevices/git/refs{/sha}","trees_url":"https://api.github.com/repos/pcdshub/pcdsdevices/git/trees{/sha}","statuses_url":"https://api.github.com/repos/pcdshub/pcdsdevices/statuses/{sha}","languages_url":"https://api.github.com/repos/pcdshub/pcdsdevices/languages","stargazers_url":"https://api.github.com/repos/pcdshub/pcdsdevices/stargazers","contributors_url":"https://api.github.com/repos/pcdshub/pcdsdevices/contributors","subscribers_url":"https://api.github.com/repos/pcdshub/pcdsdevices/subscribers","subscription_url":"https://api.github.com/repos/pcdshub/pcdsdevices/subscription","commits_url":"https://api.github.com/repos/pcdshub/pcdsdevices/commits{/sha}","git_commits_url":"https://api.github.com/repos/pcdshub/pcdsdevices/git/commits{/sha}","comments_url":"https://api.github.com/repos/pcdshub/pcdsdevices/comments{/number}","issue_comment_url":"https://api.github.com/repos/pcdshub/pcdsdevices/issues/comments{/number}","contents_url":"https://api.github.com/repos/pcdshub/pcdsdevices/contents/{+path}","compare_url":"https://api.github.com/repos/pcdshub/pcdsdevices/compare/{base}...{head}","merges_url":"https://api.github.com/repos/pcdshub/pcdsdevices/merges","archive_url":"https://api.github.com/repos/pcdshub/pcdsdevices/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/pcdshub/pcdsdevices/downloads","issues_url":"https://api.github.com/repos/pcdshub/pcdsdevices/issues{/number}","pulls_url":"https://api.github.com/repos/pcdshub/pcdsdevices/pulls{/number}","milestones_url":"https://api.github.com/repos/pcdshub/pcdsdevices/milestones{/number}","notifications_url":"https://api.github.com/repos/pcdshub/pcdsdevices/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/pcdshub/pcdsdevices/labels{/name}","releases_url":"https://api.github.com/repos/pcdshub/pcdsdevices/releases{/id}","deployments_url":"https://api.github.com/repos/pcdshub/pcdsdevices/deployments","created_at":"2017-03-14T20:31:13Z","updated_at":"2018-04-10T17:27:02Z","pushed_at":"2018-04-10T22:29:36Z","git_url":"git://github.com/pcdshub/pcdsdevices.git","ssh_url":"git@github.com:pcdshub/pcdsdevices.git","clone_url":"https://github.com/pcdshub/pcdsdevices.git","svn_url":"https://github.com/pcdshub/pcdsdevices","homepage":null,"size":8676,"stargazers_count":3,"watchers_count":3,"language":"Python","has_issues":true,"has_projects":true,"has_downloads":true,"has_wiki":true,"has_pages":true,"forks_count":9,"mirror_url":null,"archived":false,"open_issues_count":30,"license":{"key":"other","name":"Other","spdx_id":null,"url":null},"forks":9,"open_issues":30,"watchers":3,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/pcdshub/pcdsdevices/pulls/196"},"html":{"href":"https://github.com/pcdshub/pcdsdevices/pull/196"},"issue":{"href":"https://api.github.com/repos/pcdshub/pcdsdevices/issues/196"},"comments":{"href":"https://api.github.com/repos/pcdshub/pcdsdevices/issues/196/comments"},"review_comments":{"href":"https://api.github.com/repos/pcdshub/pcdsdevices/pulls/196/comments"},"review_comment":{"href":"https://api.github.com/repos/pcdshub/pcdsdevices/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/pcdshub/pcdsdevices/pulls/196/commits"},"statuses":{"href":"https://api.github.com/repos/pcdshub/pcdsdevices/statuses/66c9950496d43d7ce19b09e3766019b33dbe4ff8"}},"author_association":"CONTRIBUTOR"}}
{"actor":{"display_login":"teddyrendahl"}}