{"action":"created","issue":{"url":"https://api.github.com/repos/buttplugio/stpihkal/issues/9","repository_url":"https://api.github.com/repos/buttplugio/stpihkal","labels_url":"https://api.github.com/repos/buttplugio/stpihkal/issues/9/labels{/name}","comments_url":"https://api.github.com/repos/buttplugio/stpihkal/issues/9/comments","events_url":"https://api.github.com/repos/buttplugio/stpihkal/issues/9/events","html_url":"https://github.com/buttplugio/stpihkal/issues/9","id":275047355,"node_id":"MDU6SXNzdWUyNzUwNDczNTU=","number":9,"title":"Add shock collar protocol","user":{"login":"qdot","id":34539,"node_id":"MDQ6VXNlcjM0NTM5","avatar_url":"https://avatars1.githubusercontent.com/u/34539?v=4","gravatar_id":"","url":"https://api.github.com/users/qdot","html_url":"https://github.com/qdot","followers_url":"https://api.github.com/users/qdot/followers","following_url":"https://api.github.com/users/qdot/following{/other_user}","gists_url":"https://api.github.com/users/qdot/gists{/gist_id}","starred_url":"https://api.github.com/users/qdot/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/qdot/subscriptions","organizations_url":"https://api.github.com/users/qdot/orgs","repos_url":"https://api.github.com/users/qdot/repos","events_url":"https://api.github.com/users/qdot/events{/privacy}","received_events_url":"https://api.github.com/users/qdot/received_events","type":"User","site_admin":false},"labels":[],"state":"closed","locked":false,"assignee":null,"assignees":[],"milestone":null,"comments":1,"created_at":"2017-11-18T02:49:38Z","updated_at":"2018-09-28T22:13:41Z","closed_at":"2018-09-28T22:13:41Z","author_association":"MEMBER","body":"Collar: https://www.amazon.com/gp/product/B00W6UVROK/ref=oh_aui_detailpage_o08_s00?ie=UTF8&psc=1\r\n\r\nCode:\r\n```\r\nimport rflib\r\nimport binascii\r\nimport bitstring\r\n\r\nMHZ=1000*1000\r\n\r\n_COLLAR_BAUD_PWM=4200\r\n_COLLAR_BAUD=_COLLAR_BAUD_PWM/4\r\n_COLLAR_FREQ=434*MHZ\r\n\r\ndef _pwm_to_raw(pwm):\r\n    raw = bitstring.BitStream()\r\n    while True:\r\n        try:\r\n            nybble = pwm.read(4)\r\n            if nybble.bin == \"1110\":\r\n                raw += bitstring.Bits(\"0b1\")\r\n            elif nybble.bin == \"1000\":\r\n                raw += bitstring.Bits(\"0b0\")\r\n            elif nybble.bin == \"0000\":\r\n                pass #ew\r\n            else:\r\n                print nybble\r\n                print nybble.bin\r\n                raise ValueError(\"bad nybble\")\r\n\r\n        except bitstring.ReadError:\r\n            break\r\n\r\n    return raw\r\n\r\ndef _raw_to_pwm(raw):\r\n    pwm = bitstring.BitStream()\r\n    for bit in raw.bin:\r\n        if bit == \"0\": pwm += bitstring.Bits(\"0b1000\")\r\n        else: pwm += bitstring.Bits(\"0b1110\")\r\n\r\n    return pwm\r\n\r\n\r\ndef configure_rfcat(d):\r\n    d.setFreq(_COLLAR_FREQ)\r\n    d.setMdmModulation(rflib.MOD_ASK_OOK)\r\n    d.setMdmDRate(_COLLAR_BAUD_PWM)\r\n\r\ndef tx_raw(d, raw, repeat=8):\r\n    pwm = _raw_to_pwm(raw)\r\n    tosend = bitstring.BitString(bytes=\"\\x00\\x01\\xf0\", length=(20)) + pwm + bitstring.Bits(bytes=\"\\x00\\x00\\x00\")\r\n    # print tosend.hex\r\n    d.RFxmit(tosend.tobytes(), repeat=repeat)\r\n\r\ndef zap(d, intensity):\r\n    assert intensity <= 100 \r\n    assert intensity >= 0\r\n\r\n    template=bitstring.BitString(bin=\"010000001101110100101011100101000011111100\")\r\n    template[25:32] = bitstring.Bits(uint=intensity, length=7)\r\n    tx_raw(d, template)\r\n\r\n\r\nclass ShockCollar:\r\n    def __init__(self):\r\n        d = rflib.RfCat()\r\n        configure_rfcat(d)\r\n        self.d = d\r\n    def shock(self, intensity=1.0):\r\n        intensity_int = int(intensity*100.0)\r\n\r\n        zap(self.d, intensity_int)\r\n```"},"comment":{"url":"https://api.github.com/repos/buttplugio/stpihkal/issues/comments/425580671","html_url":"https://github.com/buttplugio/stpihkal/issues/9#issuecomment-425580671","issue_url":"https://api.github.com/repos/buttplugio/stpihkal/issues/9","id":425580671,"node_id":"MDEyOklzc3VlQ29tbWVudDQyNTU4MDY3MQ==","user":{"login":"qdot","id":34539,"node_id":"MDQ6VXNlcjM0NTM5","avatar_url":"https://avatars1.githubusercontent.com/u/34539?v=4","gravatar_id":"","url":"https://api.github.com/users/qdot","html_url":"https://github.com/qdot","followers_url":"https://api.github.com/users/qdot/followers","following_url":"https://api.github.com/users/qdot/following{/other_user}","gists_url":"https://api.github.com/users/qdot/gists{/gist_id}","starred_url":"https://api.github.com/users/qdot/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/qdot/subscriptions","organizations_url":"https://api.github.com/users/qdot/orgs","repos_url":"https://api.github.com/users/qdot/repos","events_url":"https://api.github.com/users/qdot/events{/privacy}","received_events_url":"https://api.github.com/users/qdot/received_events","type":"User","site_admin":false},"created_at":"2018-09-28T22:13:41Z","updated_at":"2018-09-28T22:13:41Z","author_association":"MEMBER","body":"Huh. Don't know why these aren't getting closed by PRs now. Thanks!"}}
{"actor":{"display_login":"qdot"}}