{"id":6850,"date":"2025-07-02T16:10:16","date_gmt":"2025-07-02T07:10:16","guid":{"rendered":"https:\/\/blog.smartlight.co.jp\/?p=6850"},"modified":"2025-07-11T14:41:18","modified_gmt":"2025-07-11T05:41:18","slug":"coolmaster%e3%82%92python%e3%81%a7%e6%93%8d%e4%bd%9c%e3%81%97%e3%80%811%e5%ba%a6%e3%81%ae%e3%83%aa%e3%82%af%e3%82%a8%e3%82%b9%e3%83%88%e3%81%a7%e8%a4%87%e6%95%b0%e6%9b%b8%e3%81%8d%e8%be%bc%e3%81%bf","status":"publish","type":"post","link":"https:\/\/blog.smartlight.co.jp\/?p=6850","title":{"rendered":"CoolMaster\u3092Python\u3067\u64cd\u4f5c\u3057\u30011\u5ea6\u306e\u30ea\u30af\u30a8\u30b9\u30c8\u3067\u8907\u6570\u66f8\u304d\u8fbc\u307f\u3092\u8a66\u3057\u3066\u307f\u305f"},"content":{"rendered":"\n<p>BACnet\u306b\u306f1\u5ea6\u306e\u30ea\u30af\u30a8\u30b9\u30c8\u3067\u8907\u6570\u306e\u60c5\u5831\u3092\u8aad\u307f\u53d6\u308b\u300cReadPropertyMultipleRequest\u300d\u306b\u5bfe\u3057\u30661\u5ea6\u306e\u30ea\u30af\u30a8\u30b9\u30c8\u3067\u8907\u6570\u306e\u66f8\u304d\u8fbc\u307f\u3092\u884c\u3046\u300cWritePropertyMultipleRequest\u300d\u304c\u3042\u308b\u3088\u3046\u306a\u306e\u3067\u4f7f\u7528\u3067\u304d\u308b\u304b\u8a66\u3057\u3066\u307f\u307e\u3057\u305f\u3002<\/p>\n\n\n\n<p>\u300cWritePropertyMultipleRequest\u300d\u306fBAC0\u3001bacpypes\u30e9\u30a4\u30d6\u30e9\u30ea\u306b\u3066\u4f7f\u7528\u3067\u304d\u308b\u3088\u3046\u3067\u3001Python\u306e\u30d0\u30fc\u30b8\u30e7\u30f3\u306f3.10\u4ee5\u964d\u306b\u5bfe\u5fdc\u3057\u3066\u3044\u308b\u3088\u3046\u3067\u3059\u3002<\/p>\n\n\n\n<p>\u7d50\u8ad6\u304b\u3089\u8a00\u3046\u3068\u300cWritePropertyMultipleRequest\u300d\u306b\u3088\u308b1\u5ea6\u306e\u30ea\u30af\u30a8\u30b9\u30c8\u3067\u8907\u6570\u66f8\u304d\u8fbc\u307f\u3059\u308b\u3053\u3068\u306f\u3067\u304d\u307e\u305b\u3093\u3067\u3057\u305f\u3002yabe\u306e\u753b\u9762\u3067\u898b\u3066\u307f\u305f\u3068\u3053\u308d\u3001\u3069\u3046\u3084\u3089CoolMaster\u304c\u300cWritePropertyMultiple\u300d\u306b\u5bfe\u5fdc\u3057\u3066\u304a\u3089\u305a\u3067\u304d\u306a\u3044\u3088\u3046\u3067\u3059\u3002\u4ed6\u306e\u65b9\u6cd5\u3082\u8abf\u3079\u3066\u307f\u307e\u3057\u305f\u304c\u300cWritePropertyMultiple\u300d\u3092\u4f7f\u3046\u4ee5\u5916\u306bBACnet\u3067\u8907\u6570\u540c\u6642\u66f8\u304d\u8fbc\u307f\u306f\u3067\u304d\u306a\u3044\u3088\u3046\u3067\u3057\u305f\u3002<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">\u7591\u4f3c\u7684\u306b\u884c\u3046<\/h3>\n\n\n\n<p>\u305d\u3053\u3067\u4eca\u56de\u306f1\u5ea6\u306e\u30ea\u30af\u30a8\u30b9\u30c8\u306b\u5bfe\u30571\u3064\u306e\u66f8\u304d\u8fbc\u307f\u3092\u884c\u3046\u3082\u306e\u3092\u30c7\u30a3\u30ec\u30a4\u3092\u304b\u3051\u308b\u3053\u3068\u3067\u8907\u6570\u306e\u30ea\u30af\u30a8\u30b9\u30c8\u3092\u3072\u3068\u3064\u306e\u51e6\u7406\u3067\u884c\u3046\u3082\u306e\u3092\u4f5c\u6210\u3057\u307e\u3057\u305f\u3002<\/p>\n\n\n\n<p>Python\u30b3\u30fc\u30c9\u306f\u3053\u3061\u3089\u3067\u3059\u3002<\/p>\n\n\n\n<div class=\"hcb_wrap\"><pre class=\"prism line-numbers lang-plain\"><code>import threading\nfrom bacpypes.app import BIPSimpleApplication\nfrom bacpypes.object import AnalogValueObject\nfrom bacpypes.apdu import ReadPropertyRequest, WritePropertyRequest\nfrom bacpypes.primitivedata import ObjectIdentifier, Real, Unsigned\nfrom bacpypes.constructeddata import Any\nfrom bacpypes.pdu import Address\nfrom bacpypes.core import run, enable_sleeping, stop\nfrom bacpypes.iocb import IOCB\nimport time\n\n# BACnet \u8a2d\u5b9a\nBACNET_DEVICE_IP = &quot;192.168.1.100&quot;\nDEVICE_ID = 64\nSETPOINT_OBJECT_ID = &quot;analogValue:256&quot;\nMODE_OBJECT_ID = &quot;multiStateValue:257&quot;\nFAN_SPEED_OBJECT_ID = &quot;multiStateValue:256&quot;\n\nLOCAL_BACNET_IP = &quot;192.168.1.168&quot; #\u81ea\u5206\u306e\u30ed\u30fc\u30ab\u30ebIP\n\nclass BACnetClient(BIPSimpleApplication):\n    def __init__(self, local_address):\n        super().__init__(None, local_address)\n\n    def read_setpoint(self):\n        print(&quot;[INFO] Setpoint \u3092\u53d6\u5f97\u4e2d...&quot;, flush=True)\n        request = ReadPropertyRequest(\n            objectIdentifier=ObjectIdentifier(SETPOINT_OBJECT_ID),\n            propertyIdentifier=&quot;presentValue&quot;\n        )\n        request.pduDestination = Address(BACNET_DEVICE_IP)\n        iocb = IOCB(request)\n        self.request_io(iocb)\n        def on_response(iocb):\n            if iocb.ioError:\n                print(f&quot;[ERROR] \u8aad\u307f\u53d6\u308a\u30a8\u30e9\u30fc: {iocb.ioError}&quot;, flush=True)\n            else:\n                value = iocb.ioResponse.propertyValue.cast_out(Real)\n                print(f&quot;[INFO] \u73fe\u5728\u306e\u30bb\u30c3\u30c8\u30dd\u30a4\u30f3\u30c8: {value}\u00b0C&quot;, flush=True)\n        iocb.add_callback(on_response)\n\n    def write_setpoint(self, new_value):\n        print(f&quot;[INFO] Setpoint \u3092 {new_value}\u00b0C \u306b\u5909\u66f4\u4e2d...&quot;, flush=True)\n        request = WritePropertyRequest(\n            objectIdentifier=ObjectIdentifier(SETPOINT_OBJECT_ID),\n            propertyIdentifier=&quot;presentValue&quot;,\n            propertyValue=Any(Real(new_value))\n        )\n        request.pduDestination = Address(BACNET_DEVICE_IP)\n        iocb = IOCB(request)\n        self.request_io(iocb)\n        def on_response(iocb):\n            if iocb.ioError:\n                print(f&quot;[ERROR] \u66f8\u304d\u8fbc\u307f\u30a8\u30e9\u30fc: {iocb.ioError}&quot;, flush=True)\n            else:\n                print(f&quot;[INFO] Setpoint \u3092 {new_value}\u00b0C \u306b\u5909\u66f4\u3057\u307e\u3057\u305f&quot;, flush=True)\n        iocb.add_callback(on_response)\n\n    def write_mode(self, mode_value):\n        print(f&quot;[INFO] \u30e2\u30fc\u30c9\u3092 {mode_value} \u306b\u5909\u66f4\u4e2d...&quot;, flush=True)\n        request = WritePropertyRequest(\n            objectIdentifier=ObjectIdentifier(MODE_OBJECT_ID),\n            propertyIdentifier=&quot;presentValue&quot;,\n            propertyValue=Any(Unsigned(mode_value))\n        )\n        request.pduDestination = Address(BACNET_DEVICE_IP)\n        iocb = IOCB(request)\n        self.request_io(iocb)\n        def on_response(iocb):\n            if iocb.ioError:\n                print(f&quot;[ERROR] \u30e2\u30fc\u30c9\u5909\u66f4\u30a8\u30e9\u30fc: {iocb.ioError}&quot;, flush=True)\n            else:\n                print(f&quot;[INFO] \u30e2\u30fc\u30c9\u3092 {mode_value} \u306b\u5909\u66f4\u3057\u307e\u3057\u305f&quot;, flush=True)\n        iocb.add_callback(on_response)\n\n    def read_mode(self):\n        print(&quot;[INFO] \u30e2\u30fc\u30c9\u3092\u53d6\u5f97\u4e2d...&quot;, flush=True)\n        request = ReadPropertyRequest(\n            objectIdentifier=ObjectIdentifier(MODE_OBJECT_ID),\n            propertyIdentifier=&quot;presentValue&quot;\n        )\n        request.pduDestination = Address(BACNET_DEVICE_IP)\n        iocb = IOCB(request)\n        self.request_io(iocb)\n        def on_response(iocb):\n            if iocb.ioError:\n                print(f&quot;[ERROR] \u8aad\u307f\u53d6\u308a\u30a8\u30e9\u30fc: {iocb.ioError}&quot;, flush=True)\n            else:\n                value = iocb.ioResponse.propertyValue.cast_out(Unsigned)\n                print(f&quot;[INFO] \u73fe\u5728\u306e\u30e2\u30fc\u30c9\u5024: {value}&quot;, flush=True)\n        iocb.add_callback(on_response)\n\n    def write_fan_speed(self, fan_speed_value):\n        print(f&quot;[INFO] \u98a8\u91cf\u3092 {fan_speed_value} \u306b\u5909\u66f4\u4e2d...&quot;, flush=True)\n        request = WritePropertyRequest(\n            objectIdentifier=ObjectIdentifier(FAN_SPEED_OBJECT_ID),\n            propertyIdentifier=&quot;presentValue&quot;,\n            propertyValue=Any(Unsigned(fan_speed_value))\n        )\n        request.pduDestination = Address(BACNET_DEVICE_IP)\n        iocb = IOCB(request)\n        self.request_io(iocb)\n        def on_response(iocb):\n            if iocb.ioError:\n                print(f&quot;[ERROR] \u98a8\u91cf\u5909\u66f4\u30a8\u30e9\u30fc: {iocb.ioError}&quot;, flush=True)\n            else:\n                print(f&quot;[INFO] \u98a8\u91cf\u3092 {fan_speed_value} \u306b\u5909\u66f4\u3057\u307e\u3057\u305f&quot;, flush=True)\n        iocb.add_callback(on_response)\n\n    def read_fan_speed(self):\n        print(&quot;[INFO] \u73fe\u5728\u306e\u98a8\u91cf\u3092\u53d6\u5f97\u4e2d...&quot;, flush=True)\n        request = ReadPropertyRequest(\n            objectIdentifier=ObjectIdentifier(FAN_SPEED_OBJECT_ID),\n            propertyIdentifier=&quot;presentValue&quot;\n        )\n        request.pduDestination = Address(BACNET_DEVICE_IP)\n        iocb = IOCB(request)\n        self.request_io(iocb)\n        def on_response(iocb):\n            if iocb.ioError:\n                print(f&quot;[ERROR] \u8aad\u307f\u53d6\u308a\u30a8\u30e9\u30fc: {iocb.ioError}&quot;, flush=True)\n            else:\n                value = iocb.ioResponse.propertyValue.cast_out(Unsigned)\n                print(f&quot;[INFO] \u73fe\u5728\u306e\u98a8\u91cf\u30e2\u30fc\u30c9\u5024: {value}&quot;, flush=True)\n        iocb.add_callback(on_response)\n\n# \u30a4\u30d9\u30f3\u30c8\u30eb\u30fc\u30d7\nclient = BACnetClient(Address(LOCAL_BACNET_IP))\n\ndef start_bacnet_loop():\n    enable_sleeping()\n    print(&quot;[INFO] BACnet \u30a4\u30d9\u30f3\u30c8\u30eb\u30fc\u30d7\u958b\u59cb...&quot;, flush=True)\n    run()\n\nthread = threading.Thread(target=start_bacnet_loop, daemon=True)\nthread.start()\n\n# \u30e1\u30a4\u30f3\u51e6\u7406\ntry:\n    time.sleep(2)\n\n    client.read_mode()\n    time.sleep(2)\n\n    client.write_mode(1)  # \u30e2\u30fc\u30c9\n    time.sleep(2)\n\n    client.write_setpoint(27.0) #\u8a2d\u5b9a\u6e29\u5ea6\n    time.sleep(2)\n\n    client.read_setpoint()\n    time.sleep(2)\n\n    client.read_fan_speed()\n    time.sleep(2)\n\n    client.write_fan_speed(1)  # \u98a8\u91cf\u5909\u66f4\n    time.sleep(2)\n\n    client.read_fan_speed()\n\n    while True:\n        time.sleep(1)\n\nexcept KeyboardInterrupt:\n    print(&quot;\\n[INFO] \u30e6\u30fc\u30b6\u30fc\u304c\u505c\u6b62\u3057\u307e\u3057\u305f\u3002BACnet\u3092\u7d42\u4e86\u3057\u307e\u3059\u3002&quot;, flush=True)\n    stop()<\/code><\/pre><\/div>\n\n\n\n<p>BACnet\u8a2d\u5b9a\u306e\u7b87\u6240\u3067\u4e0b\u8a18\u306e\u3088\u3046\u306b\u8a2d\u5b9a\u3057\u3066\u304a\u308a\u3053\u3061\u3089\u306fyabe\u3088\u308a\u30a2\u30c9\u30ec\u30b9\u3092\u8abf\u3079\u5165\u529b\u3092\u884c\u3063\u3066\u3044\u307e\u3059\u3002<\/p>\n\n\n\n<p>SETPOINT_OBJECT_ID = &#8220;analogValue:256&#8221;<br>MODE_OBJECT_ID = &#8220;multiStateValue:257&#8221;<br>FAN_SPEED_OBJECT_ID = &#8220;multiStateValue:256&#8221;<\/p>\n\n\n\n<p>\u4e0a\u304b\u3089\u6e29\u5ea6\u8a2d\u5b9a, \u30e2\u30fc\u30c9\u8a2d\u5b9a, \u98a8\u91cf\u8a2d\u5b9a\u306b\u306a\u3063\u3066\u3044\u307e\u3059\u3002<\/p>\n\n\n\n<div class=\"hcb_wrap\"><pre class=\"prism line-numbers lang-plain\"><code>client.read_mode()\ntime.sleep(2)\n\nclient.write_mode(1)\ntime.sleep(2)\n\nclient.write_setpoint(27.0)\ntime.sleep(2)<\/code><\/pre><\/div>\n\n\n\n<p>\u3053\u306e\u30b3\u30fc\u30c9\u3067\u306fBACnet\u30c7\u30d0\u30a4\u30b9\u304c\u5fdc\u7b54\u3092\u8fd4\u3059\u307e\u3067\u306e\u6642\u9593\u3092\u78ba\u4fdd\u3057\u3001\u30ea\u30af\u30a8\u30b9\u30c8\u304c\u6df7\u96d1\u3057\u306a\u3044\u3088\u3046\u306b\u3059\u308b\u305f\u3081\u306b\u30ea\u30af\u30a8\u30b9\u30c8\u3054\u3068\u306b2\u79d2\u306e\u30c7\u30a3\u30ec\u30a4\u3092\u304b\u3051\u3066\u3044\u307e\u3059\u3002<\/p>\n\n\n\n<figure class=\"wp-block-image size-full is-resized\"><img loading=\"lazy\" decoding=\"async\" width=\"491\" height=\"422\" src=\"https:\/\/blog.smartlight.co.jp\/wp-content\/uploads\/2025\/07\/image-10.png\" alt=\"\" class=\"wp-image-6851\" style=\"width:363px;height:auto\" \/><\/figure>\n\n\n\n<p>\u3053\u3061\u3089\u304c\u30b3\u30fc\u30c9\u306e\u5b9f\u884c\u7d50\u679c\u3067\u3059\u3002\u3046\u307e\u304f\uff13\u3064\u306e\u9805\u76ee\u3092\u5909\u66f4\u3059\u308b\u3053\u3068\u304c\u51fa\u6765\u307e\u3057\u305f\u3002<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">\u307e\u3068\u3081<\/h3>\n\n\n\n<p>\u4eca\u56de\u306f\u300cWritePropertyMultipleRequest\u300d\u304c\u4f7f\u3048\u308b\u306e\u304b\u8a66\u3057\u3066\u307f\u307e\u3057\u305f\u304c\u3067\u304d\u306a\u304b\u3063\u305f\u305f\u3081\u3001\u5225\u306e\u65b9\u6cd5\u3067\u4f3c\u305f\u3088\u3046\u306a\u4ed5\u69d8\u306e\u30b3\u30fc\u30c9\u306e\u4f5c\u6210\u3092\u884c\u3044\u307e\u3057\u305f\u3002\u30c7\u30d0\u30a4\u30b9\u306e\u4ed5\u69d8\u3092\u7406\u89e3\u3059\u308b\u3053\u3068\u304c\u5927\u5207\u3067\u3042\u308b\u3053\u3068\u3092\u5b66\u3073\u307e\u3057\u305f\u3002\u307e\u305f\u3001\u30ea\u30af\u30a8\u30b9\u30c8\u3092\u9001\u308b\u969b\u306e\u30c7\u30a3\u30ec\u30a4\u306e\u5fc5\u8981\u6027\u306b\u95a2\u3057\u3066\u3082\u5b66\u3073\u307e\u3057\u305f\u3002<\/p>\n","protected":false},"excerpt":{"rendered":"<p>BACnet\u306b\u306f1\u5ea6\u306e\u30ea\u30af\u30a8\u30b9\u30c8\u3067\u8907\u6570\u306e\u60c5\u5831\u3092\u8aad\u307f\u53d6\u308b\u300cReadPropertyMultipleRequest\u300d\u306b\u5bfe\u3057\u30661\u5ea6\u306e\u30ea\u30af\u30a8\u30b9\u30c8\u3067\u8907\u6570\u306e\u66f8\u304d\u8fbc\u307f\u3092\u884c\u3046\u300cWritePropertyMultipleRequest\u300d\u304c<\/p>\n","protected":false},"author":22,"featured_media":6852,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_jin_ogp_image_url":"https:\/\/blog.smartlight.co.jp\/wp-content\/uploads\/2025\/07\/thumbnails-ogp-6850.png","_jin_last_featured_id":6852,"_jetpack_memberships_contains_paid_content":false,"footnotes":""},"categories":[3],"tags":[],"class_list":["post-6850","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-intern"],"jetpack_featured_media_url":"https:\/\/blog.smartlight.co.jp\/wp-content\/uploads\/2025\/07\/thumbnails-featured-6850.png","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/blog.smartlight.co.jp\/index.php?rest_route=\/wp\/v2\/posts\/6850","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/blog.smartlight.co.jp\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blog.smartlight.co.jp\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blog.smartlight.co.jp\/index.php?rest_route=\/wp\/v2\/users\/22"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.smartlight.co.jp\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=6850"}],"version-history":[{"count":3,"href":"https:\/\/blog.smartlight.co.jp\/index.php?rest_route=\/wp\/v2\/posts\/6850\/revisions"}],"predecessor-version":[{"id":6868,"href":"https:\/\/blog.smartlight.co.jp\/index.php?rest_route=\/wp\/v2\/posts\/6850\/revisions\/6868"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/blog.smartlight.co.jp\/index.php?rest_route=\/wp\/v2\/media\/6852"}],"wp:attachment":[{"href":"https:\/\/blog.smartlight.co.jp\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=6850"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.smartlight.co.jp\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=6850"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.smartlight.co.jp\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=6850"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}