├── .gitattributes ├── .gitignore ├── Faceplate ├── Brightness.png ├── Touchphat Plate Cut.dxf ├── Touchphat Plate Cut.svg ├── Touchphat Plate.svg ├── faceplate.rld └── runtp.png ├── PiHue ├── PiHue.service └── code │ ├── PiHueLightList.py │ ├── PiHueRoom.py │ ├── colourconfig.py │ ├── hueconfig.cfg │ └── huecontrol.py ├── README.md └── code ├── .gitattributes └── .gitignore /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Byte-compiled / optimized / DLL files 2 | __pycache__/ 3 | *.py[cod] 4 | *$py.class 5 | 6 | # C extensions 7 | *.so 8 | 9 | # Distribution / packaging 10 | .Python 11 | env/ 12 | build/ 13 | develop-eggs/ 14 | dist/ 15 | downloads/ 16 | eggs/ 17 | .eggs/ 18 | lib/ 19 | lib64/ 20 | parts/ 21 | sdist/ 22 | var/ 23 | wheels/ 24 | *.egg-info/ 25 | .installed.cfg 26 | *.egg 27 | 28 | # PyInstaller 29 | # Usually these files are written by a python script from a template 30 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 31 | *.manifest 32 | *.spec 33 | 34 | # Installer logs 35 | pip-log.txt 36 | pip-delete-this-directory.txt 37 | 38 | # Unit test / coverage reports 39 | htmlcov/ 40 | .tox/ 41 | .coverage 42 | .coverage.* 43 | .cache 44 | nosetests.xml 45 | coverage.xml 46 | *,cover 47 | .hypothesis/ 48 | 49 | # Translations 50 | *.mo 51 | *.pot 52 | 53 | # Django stuff: 54 | *.log 55 | local_settings.py 56 | 57 | # Flask stuff: 58 | instance/ 59 | .webassets-cache 60 | 61 | # Scrapy stuff: 62 | .scrapy 63 | 64 | # Sphinx documentation 65 | docs/_build/ 66 | 67 | # PyBuilder 68 | target/ 69 | 70 | # Jupyter Notebook 71 | .ipynb_checkpoints 72 | 73 | # pyenv 74 | .python-version 75 | 76 | # celery beat schedule file 77 | celerybeat-schedule 78 | 79 | # dotenv 80 | .env 81 | 82 | # virtualenv 83 | .venv/ 84 | venv/ 85 | ENV/ 86 | 87 | # Spyder project settings 88 | .spyderproject 89 | 90 | # Rope project settings 91 | .ropeproject 92 | .idea/Hut8Hue.iml 93 | .idea/deployment.xml 94 | .idea/inspectionProfiles/profiles_settings.xml 95 | .idea/misc.xml 96 | .idea/modules.xml 97 | .idea/remote-mappings.xml 98 | .idea/vcs.xml 99 | .idea/webServers.xml 100 | .idea/workspace.xml 101 | grouptest.py 102 | .idea/preferred-vcs.xml 103 | /.python_hue 104 | -------------------------------------------------------------------------------- /Faceplate/Brightness.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeekyTim/PiHue/138e6b07ee0e99f3554fcc7ed1ccdf614d627b16/Faceplate/Brightness.png -------------------------------------------------------------------------------- /Faceplate/Touchphat Plate Cut.dxf: -------------------------------------------------------------------------------- 1 | 0 2 | SECTION 3 | 2 4 | HEADER 5 | 9 6 | $ACADVER 7 | 1 8 | AC1014 9 | 9 10 | $HANDSEED 11 | 5 12 | FFFF 13 | 9 14 | $MEASUREMENT 15 | 70 16 | 1 17 | 0 18 | ENDSEC 19 | 0 20 | SECTION 21 | 2 22 | TABLES 23 | 0 24 | TABLE 25 | 2 26 | VPORT 27 | 5 28 | 8 29 | 330 30 | 0 31 | 100 32 | AcDbSymbolTable 33 | 70 34 | 4 35 | 0 36 | VPORT 37 | 5 38 | 2E 39 | 330 40 | 8 41 | 100 42 | AcDbSymbolTableRecord 43 | 100 44 | AcDbViewportTableRecord 45 | 2 46 | *ACTIVE 47 | 70 48 | 0 49 | 10 50 | 0.0 51 | 20 52 | 0.0 53 | 11 54 | 1.0 55 | 21 56 | 1.0 57 | 12 58 | 210.0 59 | 22 60 | 148.5 61 | 13 62 | 0.0 63 | 23 64 | 0.0 65 | 14 66 | 10.0 67 | 24 68 | 10.0 69 | 15 70 | 10.0 71 | 25 72 | 10.0 73 | 16 74 | 0.0 75 | 26 76 | 0.0 77 | 36 78 | 1.0 79 | 17 80 | 0.0 81 | 27 82 | 0.0 83 | 37 84 | 0.0 85 | 40 86 | 341.0 87 | 41 88 | 1.24 89 | 42 90 | 50.0 91 | 43 92 | 0.0 93 | 44 94 | 0.0 95 | 50 96 | 0.0 97 | 51 98 | 0.0 99 | 71 100 | 0 101 | 72 102 | 100 103 | 73 104 | 1 105 | 74 106 | 3 107 | 75 108 | 0 109 | 76 110 | 0 111 | 77 112 | 0 113 | 78 114 | 0 115 | 0 116 | ENDTAB 117 | 0 118 | TABLE 119 | 2 120 | LTYPE 121 | 5 122 | 5 123 | 330 124 | 0 125 | 100 126 | AcDbSymbolTable 127 | 70 128 | 1 129 | 0 130 | LTYPE 131 | 5 132 | 14 133 | 330 134 | 5 135 | 100 136 | AcDbSymbolTableRecord 137 | 100 138 | AcDbLinetypeTableRecord 139 | 2 140 | BYBLOCK 141 | 70 142 | 0 143 | 3 144 | 145 | 72 146 | 65 147 | 73 148 | 0 149 | 40 150 | 0.0 151 | 0 152 | LTYPE 153 | 5 154 | 15 155 | 330 156 | 5 157 | 100 158 | AcDbSymbolTableRecord 159 | 100 160 | AcDbLinetypeTableRecord 161 | 2 162 | BYLAYER 163 | 70 164 | 0 165 | 3 166 | 167 | 72 168 | 65 169 | 73 170 | 0 171 | 40 172 | 0.0 173 | 0 174 | LTYPE 175 | 5 176 | 16 177 | 330 178 | 5 179 | 100 180 | AcDbSymbolTableRecord 181 | 100 182 | AcDbLinetypeTableRecord 183 | 2 184 | CONTINUOUS 185 | 70 186 | 0 187 | 3 188 | Solid line 189 | 72 190 | 65 191 | 73 192 | 0 193 | 40 194 | 0.0 195 | 0 196 | ENDTAB 197 | 0 198 | TABLE 199 | 2 200 | LAYER 201 | 5 202 | 2 203 | 100 204 | AcDbSymbolTable 205 | 70 206 | 2 207 | 0 208 | LAYER 209 | 5 210 | 50 211 | 100 212 | AcDbSymbolTableRecord 213 | 100 214 | AcDbLayerTableRecord 215 | 2 216 | 0 217 | 70 218 | 0 219 | 6 220 | CONTINUOUS 221 | 0 222 | LAYER 223 | 5 224 | 51 225 | 100 226 | AcDbSymbolTableRecord 227 | 100 228 | AcDbLayerTableRecord 229 | 2 230 | Layer_1 231 | 70 232 | 0 233 | 6 234 | CONTINUOUS 235 | 0 236 | ENDTAB 237 | 0 238 | TABLE 239 | 2 240 | STYLE 241 | 5 242 | 3 243 | 330 244 | 0 245 | 100 246 | AcDbSymbolTable 247 | 70 248 | 1 249 | 0 250 | STYLE 251 | 5 252 | 11 253 | 330 254 | 3 255 | 100 256 | AcDbSymbolTableRecord 257 | 100 258 | AcDbTextStyleTableRecord 259 | 2 260 | STANDARD 261 | 70 262 | 0 263 | 40 264 | 0.0 265 | 41 266 | 1.0 267 | 50 268 | 0.0 269 | 71 270 | 0 271 | 42 272 | 2.5 273 | 3 274 | txt 275 | 4 276 | 277 | 0 278 | ENDTAB 279 | 0 280 | TABLE 281 | 2 282 | VIEW 283 | 5 284 | 6 285 | 330 286 | 0 287 | 100 288 | AcDbSymbolTable 289 | 70 290 | 0 291 | 0 292 | ENDTAB 293 | 0 294 | TABLE 295 | 2 296 | UCS 297 | 5 298 | 7 299 | 330 300 | 0 301 | 100 302 | AcDbSymbolTable 303 | 70 304 | 0 305 | 0 306 | ENDTAB 307 | 0 308 | TABLE 309 | 2 310 | APPID 311 | 5 312 | 9 313 | 330 314 | 0 315 | 100 316 | AcDbSymbolTable 317 | 70 318 | 2 319 | 0 320 | APPID 321 | 5 322 | 12 323 | 330 324 | 9 325 | 100 326 | AcDbSymbolTableRecord 327 | 100 328 | AcDbRegAppTableRecord 329 | 2 330 | ACAD 331 | 70 332 | 0 333 | 0 334 | ENDTAB 335 | 0 336 | TABLE 337 | 2 338 | DIMSTYLE 339 | 5 340 | A 341 | 330 342 | 0 343 | 100 344 | AcDbSymbolTable 345 | 70 346 | 1 347 | 0 348 | DIMSTYLE 349 | 105 350 | 27 351 | 330 352 | A 353 | 100 354 | AcDbSymbolTableRecord 355 | 100 356 | AcDbDimStyleTableRecord 357 | 2 358 | ISO-25 359 | 70 360 | 0 361 | 3 362 | 363 | 4 364 | 365 | 5 366 | 367 | 6 368 | 369 | 7 370 | 371 | 40 372 | 1.0 373 | 41 374 | 2.5 375 | 42 376 | 0.625 377 | 43 378 | 3.75 379 | 44 380 | 1.25 381 | 45 382 | 0.0 383 | 46 384 | 0.0 385 | 47 386 | 0.0 387 | 48 388 | 0.0 389 | 140 390 | 2.5 391 | 141 392 | 2.5 393 | 142 394 | 0.0 395 | 143 396 | 0.03937007874016 397 | 144 398 | 1.0 399 | 145 400 | 0.0 401 | 146 402 | 1.0 403 | 147 404 | 0.625 405 | 71 406 | 0 407 | 72 408 | 0 409 | 73 410 | 0 411 | 74 412 | 0 413 | 75 414 | 0 415 | 76 416 | 0 417 | 77 418 | 1 419 | 78 420 | 8 421 | 170 422 | 0 423 | 171 424 | 3 425 | 172 426 | 1 427 | 173 428 | 0 429 | 174 430 | 0 431 | 175 432 | 0 433 | 176 434 | 0 435 | 177 436 | 0 437 | 178 438 | 0 439 | 270 440 | 2 441 | 271 442 | 2 443 | 272 444 | 2 445 | 273 446 | 2 447 | 274 448 | 3 449 | 340 450 | 11 451 | 275 452 | 0 453 | 280 454 | 0 455 | 281 456 | 0 457 | 282 458 | 0 459 | 283 460 | 0 461 | 284 462 | 8 463 | 285 464 | 0 465 | 286 466 | 0 467 | 287 468 | 3 469 | 288 470 | 0 471 | 0 472 | ENDTAB 473 | 0 474 | TABLE 475 | 2 476 | BLOCK_RECORD 477 | 5 478 | 1 479 | 330 480 | 0 481 | 100 482 | AcDbSymbolTable 483 | 70 484 | 1 485 | 0 486 | BLOCK_RECORD 487 | 5 488 | 1F 489 | 330 490 | 1 491 | 100 492 | AcDbSymbolTableRecord 493 | 100 494 | AcDbBlockTableRecord 495 | 2 496 | *MODEL_SPACE 497 | 0 498 | BLOCK_RECORD 499 | 5 500 | 1B 501 | 330 502 | 1 503 | 100 504 | AcDbSymbolTableRecord 505 | 100 506 | AcDbBlockTableRecord 507 | 2 508 | *PAPER_SPACE 509 | 0 510 | ENDTAB 511 | 0 512 | ENDSEC 513 | 0 514 | SECTION 515 | 2 516 | BLOCKS 517 | 0 518 | BLOCK 519 | 5 520 | 20 521 | 330 522 | 1F 523 | 100 524 | AcDbEntity 525 | 8 526 | 0 527 | 100 528 | AcDbBlockBegin 529 | 2 530 | *MODEL_SPACE 531 | 70 532 | 0 533 | 10 534 | 0.0 535 | 20 536 | 0.0 537 | 30 538 | 0.0 539 | 3 540 | *MODEL_SPACE 541 | 1 542 | 543 | 0 544 | ENDBLK 545 | 5 546 | 21 547 | 330 548 | 1F 549 | 100 550 | AcDbEntity 551 | 8 552 | 0 553 | 100 554 | AcDbBlockEnd 555 | 0 556 | BLOCK 557 | 5 558 | 1C 559 | 330 560 | 1B 561 | 100 562 | AcDbEntity 563 | 67 564 | 1 565 | 8 566 | 0 567 | 100 568 | AcDbBlockBegin 569 | 2 570 | *PAPER_SPACE 571 | 1 572 | 573 | 0 574 | ENDBLK 575 | 5 576 | 1D 577 | 330 578 | 1B 579 | 100 580 | AcDbEntity 581 | 67 582 | 1 583 | 8 584 | 0 585 | 100 586 | AcDbBlockEnd 587 | 0 588 | ENDSEC 589 | 0 590 | SECTION 591 | 2 592 | ENTITIES 593 | 0 594 | SPLINE 595 | 5 596 | 100 597 | 100 598 | AcDbEntity 599 | 8 600 | Layer_1 601 | 62 602 | 7 603 | 100 604 | AcDbSpline 605 | 70 606 | 8 607 | 71 608 | 3 609 | 72 610 | 8 611 | 73 612 | 4 613 | 74 614 | 0 615 | 40 616 | 0 617 | 40 618 | 0 619 | 40 620 | 0 621 | 40 622 | 0 623 | 40 624 | 1 625 | 40 626 | 1 627 | 40 628 | 1 629 | 40 630 | 1 631 | 10 632 | 79.936054 633 | 20 634 | 75.159010 635 | 30 636 | 0.0 637 | 10 638 | 79.936054 639 | 20 640 | 75.052603 641 | 30 642 | 0.0 643 | 10 644 | 79.878653 645 | 20 646 | 74.954597 647 | 30 648 | 0.0 649 | 10 650 | 79.786946 651 | 20 652 | 74.901394 653 | 30 654 | 0.0 655 | 0 656 | SPLINE 657 | 5 658 | 101 659 | 100 660 | AcDbEntity 661 | 8 662 | Layer_1 663 | 62 664 | 7 665 | 100 666 | AcDbSpline 667 | 70 668 | 8 669 | 71 670 | 3 671 | 72 672 | 8 673 | 73 674 | 4 675 | 74 676 | 0 677 | 40 678 | 0 679 | 40 680 | 0 681 | 40 682 | 0 683 | 40 684 | 0 685 | 40 686 | 1 687 | 40 688 | 1 689 | 40 690 | 1 691 | 40 692 | 1 693 | 10 694 | 79.786946 695 | 20 696 | 74.901394 697 | 30 698 | 0.0 699 | 10 700 | 79.694540 701 | 20 702 | 74.848191 703 | 30 704 | 0.0 705 | 10 706 | 79.581134 707 | 20 708 | 74.848191 709 | 30 710 | 0.0 711 | 10 712 | 79.489427 713 | 20 714 | 74.901394 715 | 30 716 | 0.0 717 | 0 718 | SPLINE 719 | 5 720 | 102 721 | 100 722 | AcDbEntity 723 | 8 724 | Layer_1 725 | 62 726 | 7 727 | 100 728 | AcDbSpline 729 | 70 730 | 8 731 | 71 732 | 3 733 | 72 734 | 8 735 | 73 736 | 4 737 | 74 738 | 0 739 | 40 740 | 0 741 | 40 742 | 0 743 | 40 744 | 0 745 | 40 746 | 0 747 | 40 748 | 1 749 | 40 750 | 1 751 | 40 752 | 1 753 | 40 754 | 1 755 | 10 756 | 79.489427 757 | 20 758 | 74.901394 759 | 30 760 | 0.0 761 | 10 762 | 79.397021 763 | 20 764 | 74.954597 765 | 30 766 | 0.0 767 | 10 768 | 79.340318 769 | 20 770 | 75.052603 771 | 30 772 | 0.0 773 | 10 774 | 79.340318 775 | 20 776 | 75.159010 777 | 30 778 | 0.0 779 | 0 780 | SPLINE 781 | 5 782 | 103 783 | 100 784 | AcDbEntity 785 | 8 786 | Layer_1 787 | 62 788 | 7 789 | 100 790 | AcDbSpline 791 | 70 792 | 8 793 | 71 794 | 3 795 | 72 796 | 8 797 | 73 798 | 4 799 | 74 800 | 0 801 | 40 802 | 0 803 | 40 804 | 0 805 | 40 806 | 0 807 | 40 808 | 0 809 | 40 810 | 1 811 | 40 812 | 1 813 | 40 814 | 1 815 | 40 816 | 1 817 | 10 818 | 79.340318 819 | 20 820 | 75.159010 821 | 30 822 | 0.0 823 | 10 824 | 79.340318 825 | 20 826 | 75.265416 827 | 30 828 | 0.0 829 | 10 830 | 79.397021 831 | 20 832 | 75.363422 833 | 30 834 | 0.0 835 | 10 836 | 79.489427 837 | 20 838 | 75.416626 839 | 30 840 | 0.0 841 | 0 842 | SPLINE 843 | 5 844 | 104 845 | 100 846 | AcDbEntity 847 | 8 848 | Layer_1 849 | 62 850 | 7 851 | 100 852 | AcDbSpline 853 | 70 854 | 8 855 | 71 856 | 3 857 | 72 858 | 8 859 | 73 860 | 4 861 | 74 862 | 0 863 | 40 864 | 0 865 | 40 866 | 0 867 | 40 868 | 0 869 | 40 870 | 0 871 | 40 872 | 1 873 | 40 874 | 1 875 | 40 876 | 1 877 | 40 878 | 1 879 | 10 880 | 79.489427 881 | 20 882 | 75.416626 883 | 30 884 | 0.0 885 | 10 886 | 79.581134 887 | 20 888 | 75.469829 889 | 30 890 | 0.0 891 | 10 892 | 79.694540 893 | 20 894 | 75.469829 895 | 30 896 | 0.0 897 | 10 898 | 79.786946 899 | 20 900 | 75.416626 901 | 30 902 | 0.0 903 | 0 904 | SPLINE 905 | 5 906 | 105 907 | 100 908 | AcDbEntity 909 | 8 910 | Layer_1 911 | 62 912 | 7 913 | 100 914 | AcDbSpline 915 | 70 916 | 8 917 | 71 918 | 3 919 | 72 920 | 8 921 | 73 922 | 4 923 | 74 924 | 0 925 | 40 926 | 0 927 | 40 928 | 0 929 | 40 930 | 0 931 | 40 932 | 0 933 | 40 934 | 1 935 | 40 936 | 1 937 | 40 938 | 1 939 | 40 940 | 1 941 | 10 942 | 79.786946 943 | 20 944 | 75.416626 945 | 30 946 | 0.0 947 | 10 948 | 79.878653 949 | 20 950 | 75.363422 951 | 30 952 | 0.0 953 | 10 954 | 79.936054 955 | 20 956 | 75.265416 957 | 30 958 | 0.0 959 | 10 960 | 79.936054 961 | 20 962 | 75.159010 963 | 30 964 | 0.0 965 | 0 966 | SPLINE 967 | 5 968 | 106 969 | 100 970 | AcDbEntity 971 | 8 972 | Layer_1 973 | 62 974 | 7 975 | 100 976 | AcDbSpline 977 | 70 978 | 8 979 | 71 980 | 3 981 | 72 982 | 8 983 | 73 984 | 4 985 | 74 986 | 0 987 | 40 988 | 0 989 | 40 990 | 0 991 | 40 992 | 0 993 | 40 994 | 0 995 | 40 996 | 1 997 | 40 998 | 1 999 | 40 1000 | 1 1001 | 40 1002 | 1 1003 | 10 1004 | 52.898670 1005 | 20 1006 | 65.381191 1007 | 30 1008 | 0.0 1009 | 10 1010 | 52.543963 1011 | 20 1012 | 65.381191 1013 | 30 1014 | 0.0 1015 | 10 1016 | 52.258376 1017 | 20 1018 | 65.048982 1019 | 30 1020 | 0.0 1021 | 10 1022 | 52.258376 1023 | 20 1024 | 64.636301 1025 | 30 1026 | 0.0 1027 | 0 1028 | LWPOLYLINE 1029 | 5 1030 | 107 1031 | 100 1032 | AcDbEntity 1033 | 8 1034 | Layer_1 1035 | 62 1036 | 7 1037 | 100 1038 | AcDbPolyline 1039 | 90 1040 | 1 1041 | 70 1042 | 1 1043 | 10 1044 | 79.936054 1045 | 20 1046 | 75.159010 1047 | 30 1048 | 0.0 1049 | 0 1050 | SPLINE 1051 | 5 1052 | 108 1053 | 100 1054 | AcDbEntity 1055 | 8 1056 | Layer_1 1057 | 62 1058 | 7 1059 | 100 1060 | AcDbSpline 1061 | 70 1062 | 8 1063 | 71 1064 | 3 1065 | 72 1066 | 8 1067 | 73 1068 | 4 1069 | 74 1070 | 0 1071 | 40 1072 | 0 1073 | 40 1074 | 0 1075 | 40 1076 | 0 1077 | 40 1078 | 0 1079 | 40 1080 | 1 1081 | 40 1082 | 1 1083 | 40 1084 | 1 1085 | 40 1086 | 1 1087 | 10 1088 | 54.639618 1089 | 20 1090 | 63.396869 1091 | 30 1092 | 0.0 1093 | 10 1094 | 54.786197 1095 | 20 1096 | 63.396869 1097 | 30 1098 | 0.0 1099 | 10 1100 | 54.904321 1101 | 20 1102 | 63.278744 1103 | 30 1104 | 0.0 1105 | 10 1106 | 54.904321 1107 | 20 1108 | 63.132165 1109 | 30 1110 | 0.0 1111 | 0 1112 | LWPOLYLINE 1113 | 5 1114 | 109 1115 | 100 1116 | AcDbEntity 1117 | 8 1118 | Layer_1 1119 | 62 1120 | 7 1121 | 100 1122 | AcDbPolyline 1123 | 90 1124 | 5 1125 | 70 1126 | 0 1127 | 10 1128 | 52.258376 1129 | 20 1130 | 64.636301 1131 | 30 1132 | 0.0 1133 | 10 1134 | 52.258376 1135 | 20 1136 | 63.396869 1137 | 30 1138 | 0.0 1139 | 10 1140 | 52.523080 1141 | 20 1142 | 63.396869 1143 | 30 1144 | 0.0 1145 | 10 1146 | 52.777256 1147 | 20 1148 | 63.396869 1149 | 30 1150 | 0.0 1151 | 10 1152 | 54.639618 1153 | 20 1154 | 63.396869 1155 | 30 1156 | 0.0 1157 | 0 1158 | SPLINE 1159 | 5 1160 | 10a 1161 | 100 1162 | AcDbEntity 1163 | 8 1164 | Layer_1 1165 | 62 1166 | 7 1167 | 100 1168 | AcDbSpline 1169 | 70 1170 | 8 1171 | 71 1172 | 3 1173 | 72 1174 | 8 1175 | 73 1176 | 4 1177 | 74 1178 | 0 1179 | 40 1180 | 0 1181 | 40 1182 | 0 1183 | 40 1184 | 0 1185 | 40 1186 | 0 1187 | 40 1188 | 1 1189 | 40 1190 | 1 1191 | 40 1192 | 1 1193 | 40 1194 | 1 1195 | 10 1196 | 66.810391 1197 | 20 1198 | 63.132165 1199 | 30 1200 | 0.0 1201 | 10 1202 | 66.810391 1203 | 20 1204 | 63.278744 1205 | 30 1206 | 0.0 1207 | 10 1208 | 66.928516 1209 | 20 1210 | 63.396869 1211 | 30 1212 | 0.0 1213 | 10 1214 | 67.075095 1215 | 20 1216 | 63.396869 1217 | 30 1218 | 0.0 1219 | 0 1220 | LWPOLYLINE 1221 | 5 1222 | 10b 1223 | 100 1224 | AcDbEntity 1225 | 8 1226 | Layer_1 1227 | 62 1228 | 7 1229 | 100 1230 | AcDbPolyline 1231 | 90 1232 | 8 1233 | 70 1234 | 0 1235 | 10 1236 | 54.904321 1237 | 20 1238 | 63.132165 1239 | 30 1240 | 0.0 1241 | 10 1242 | 54.904321 1243 | 20 1244 | 62.016746 1245 | 30 1246 | 0.0 1247 | 10 1248 | 54.904321 1249 | 20 1250 | 60.618711 1251 | 30 1252 | 0.0 1253 | 10 1254 | 54.904321 1255 | 20 1256 | 60.354143 1257 | 30 1258 | 0.0 1259 | 10 1260 | 66.810391 1261 | 20 1262 | 60.354143 1263 | 30 1264 | 0.0 1265 | 10 1266 | 66.810391 1267 | 20 1268 | 60.618711 1269 | 30 1270 | 0.0 1271 | 10 1272 | 66.810391 1273 | 20 1274 | 62.016746 1275 | 30 1276 | 0.0 1277 | 10 1278 | 66.810391 1279 | 20 1280 | 63.132165 1281 | 30 1282 | 0.0 1283 | 0 1284 | SPLINE 1285 | 5 1286 | 10c 1287 | 100 1288 | AcDbEntity 1289 | 8 1290 | Layer_1 1291 | 62 1292 | 7 1293 | 100 1294 | AcDbSpline 1295 | 70 1296 | 8 1297 | 71 1298 | 3 1299 | 72 1300 | 8 1301 | 73 1302 | 4 1303 | 74 1304 | 0 1305 | 40 1306 | 0 1307 | 40 1308 | 0 1309 | 40 1310 | 0 1311 | 40 1312 | 0 1313 | 40 1314 | 1 1315 | 40 1316 | 1 1317 | 40 1318 | 1 1319 | 40 1320 | 1 1321 | 10 1322 | 69.456337 1323 | 20 1324 | 64.636301 1325 | 30 1326 | 0.0 1327 | 10 1328 | 69.456337 1329 | 20 1330 | 65.048982 1331 | 30 1332 | 0.0 1333 | 10 1334 | 69.170750 1335 | 20 1336 | 65.381191 1337 | 30 1338 | 0.0 1339 | 10 1340 | 68.816043 1341 | 20 1342 | 65.381191 1343 | 30 1344 | 0.0 1345 | 0 1346 | LWPOLYLINE 1347 | 5 1348 | 10d 1349 | 100 1350 | AcDbEntity 1351 | 8 1352 | Layer_1 1353 | 62 1354 | 7 1355 | 100 1356 | AcDbPolyline 1357 | 90 1358 | 5 1359 | 70 1360 | 0 1361 | 10 1362 | 67.075095 1363 | 20 1364 | 63.396869 1365 | 30 1366 | 0.0 1367 | 10 1368 | 68.937457 1369 | 20 1370 | 63.396869 1371 | 30 1372 | 0.0 1373 | 10 1374 | 69.191632 1375 | 20 1376 | 63.396869 1377 | 30 1378 | 0.0 1379 | 10 1380 | 69.456337 1381 | 20 1382 | 63.396869 1383 | 30 1384 | 0.0 1385 | 10 1386 | 69.456337 1387 | 20 1388 | 64.636301 1389 | 30 1390 | 0.0 1391 | 0 1392 | SPLINE 1393 | 5 1394 | 10e 1395 | 100 1396 | AcDbEntity 1397 | 8 1398 | Layer_1 1399 | 62 1400 | 7 1401 | 100 1402 | AcDbSpline 1403 | 70 1404 | 8 1405 | 71 1406 | 3 1407 | 72 1408 | 8 1409 | 73 1410 | 4 1411 | 74 1412 | 0 1413 | 40 1414 | 0 1415 | 40 1416 | 0 1417 | 40 1418 | 0 1419 | 40 1420 | 0 1421 | 40 1422 | 1 1423 | 40 1424 | 1 1425 | 40 1426 | 1 1427 | 40 1428 | 1 1429 | 10 1430 | 53.184430 1431 | 20 1432 | 64.852057 1433 | 30 1434 | 0.0 1435 | 10 1436 | 53.289703 1437 | 20 1438 | 64.852068 1439 | 30 1440 | 0.0 1441 | 10 1442 | 53.390667 1443 | 20 1444 | 64.810254 1445 | 30 1446 | 0.0 1447 | 10 1448 | 53.465107 1449 | 20 1450 | 64.735815 1451 | 30 1452 | 0.0 1453 | 0 1454 | SPLINE 1455 | 5 1456 | 10f 1457 | 100 1458 | AcDbEntity 1459 | 8 1460 | Layer_1 1461 | 62 1462 | 7 1463 | 100 1464 | AcDbSpline 1465 | 70 1466 | 8 1467 | 71 1468 | 3 1469 | 72 1470 | 8 1471 | 73 1472 | 4 1473 | 74 1474 | 0 1475 | 40 1476 | 0 1477 | 40 1478 | 0 1479 | 40 1480 | 0 1481 | 40 1482 | 0 1483 | 40 1484 | 1 1485 | 40 1486 | 1 1487 | 40 1488 | 1 1489 | 40 1490 | 1 1491 | 10 1492 | 53.465107 1493 | 20 1494 | 64.735815 1495 | 30 1496 | 0.0 1497 | 10 1498 | 53.539546 1499 | 20 1500 | 64.661375 1501 | 30 1502 | 0.0 1503 | 10 1504 | 53.581360 1505 | 20 1506 | 64.560411 1507 | 30 1508 | 0.0 1509 | 10 1510 | 53.581349 1511 | 20 1512 | 64.455138 1513 | 30 1514 | 0.0 1515 | 0 1516 | SPLINE 1517 | 5 1518 | 110 1519 | 100 1520 | AcDbEntity 1521 | 8 1522 | Layer_1 1523 | 62 1524 | 7 1525 | 100 1526 | AcDbSpline 1527 | 70 1528 | 8 1529 | 71 1530 | 3 1531 | 72 1532 | 8 1533 | 73 1534 | 4 1535 | 74 1536 | 0 1537 | 40 1538 | 0 1539 | 40 1540 | 0 1541 | 40 1542 | 0 1543 | 40 1544 | 0 1545 | 40 1546 | 1 1547 | 40 1548 | 1 1549 | 40 1550 | 1 1551 | 40 1552 | 1 1553 | 10 1554 | 53.581349 1555 | 20 1556 | 64.455138 1557 | 30 1558 | 0.0 1559 | 10 1560 | 53.581360 1561 | 20 1562 | 64.349865 1563 | 30 1564 | 0.0 1565 | 10 1566 | 53.539546 1567 | 20 1568 | 64.248900 1569 | 30 1570 | 0.0 1571 | 10 1572 | 53.465107 1573 | 20 1574 | 64.174461 1575 | 30 1576 | 0.0 1577 | 0 1578 | SPLINE 1579 | 5 1580 | 111 1581 | 100 1582 | AcDbEntity 1583 | 8 1584 | Layer_1 1585 | 62 1586 | 7 1587 | 100 1588 | AcDbSpline 1589 | 70 1590 | 8 1591 | 71 1592 | 3 1593 | 72 1594 | 8 1595 | 73 1596 | 4 1597 | 74 1598 | 0 1599 | 40 1600 | 0 1601 | 40 1602 | 0 1603 | 40 1604 | 0 1605 | 40 1606 | 0 1607 | 40 1608 | 1 1609 | 40 1610 | 1 1611 | 40 1612 | 1 1613 | 40 1614 | 1 1615 | 10 1616 | 53.465107 1617 | 20 1618 | 64.174461 1619 | 30 1620 | 0.0 1621 | 10 1622 | 53.390667 1623 | 20 1624 | 64.100021 1625 | 30 1626 | 0.0 1627 | 10 1628 | 53.289703 1629 | 20 1630 | 64.058207 1631 | 30 1632 | 0.0 1633 | 10 1634 | 53.184430 1635 | 20 1636 | 64.058219 1637 | 30 1638 | 0.0 1639 | 0 1640 | SPLINE 1641 | 5 1642 | 112 1643 | 100 1644 | AcDbEntity 1645 | 8 1646 | Layer_1 1647 | 62 1648 | 7 1649 | 100 1650 | AcDbSpline 1651 | 70 1652 | 8 1653 | 71 1654 | 3 1655 | 72 1656 | 8 1657 | 73 1658 | 4 1659 | 74 1660 | 0 1661 | 40 1662 | 0 1663 | 40 1664 | 0 1665 | 40 1666 | 0 1667 | 40 1668 | 0 1669 | 40 1670 | 1 1671 | 40 1672 | 1 1673 | 40 1674 | 1 1675 | 40 1676 | 1 1677 | 10 1678 | 53.184430 1679 | 20 1680 | 64.058219 1681 | 30 1682 | 0.0 1683 | 10 1684 | 53.079157 1685 | 20 1686 | 64.058207 1687 | 30 1688 | 0.0 1689 | 10 1690 | 52.978192 1691 | 20 1692 | 64.100021 1693 | 30 1694 | 0.0 1695 | 10 1696 | 52.903753 1697 | 20 1698 | 64.174461 1699 | 30 1700 | 0.0 1701 | 0 1702 | SPLINE 1703 | 5 1704 | 113 1705 | 100 1706 | AcDbEntity 1707 | 8 1708 | Layer_1 1709 | 62 1710 | 7 1711 | 100 1712 | AcDbSpline 1713 | 70 1714 | 8 1715 | 71 1716 | 3 1717 | 72 1718 | 8 1719 | 73 1720 | 4 1721 | 74 1722 | 0 1723 | 40 1724 | 0 1725 | 40 1726 | 0 1727 | 40 1728 | 0 1729 | 40 1730 | 0 1731 | 40 1732 | 1 1733 | 40 1734 | 1 1735 | 40 1736 | 1 1737 | 40 1738 | 1 1739 | 10 1740 | 52.903753 1741 | 20 1742 | 64.174461 1743 | 30 1744 | 0.0 1745 | 10 1746 | 52.829313 1747 | 20 1748 | 64.248900 1749 | 30 1750 | 0.0 1751 | 10 1752 | 52.787499 1753 | 20 1754 | 64.349865 1755 | 30 1756 | 0.0 1757 | 10 1758 | 52.787511 1759 | 20 1760 | 64.455138 1761 | 30 1762 | 0.0 1763 | 0 1764 | SPLINE 1765 | 5 1766 | 114 1767 | 100 1768 | AcDbEntity 1769 | 8 1770 | Layer_1 1771 | 62 1772 | 7 1773 | 100 1774 | AcDbSpline 1775 | 70 1776 | 8 1777 | 71 1778 | 3 1779 | 72 1780 | 8 1781 | 73 1782 | 4 1783 | 74 1784 | 0 1785 | 40 1786 | 0 1787 | 40 1788 | 0 1789 | 40 1790 | 0 1791 | 40 1792 | 0 1793 | 40 1794 | 1 1795 | 40 1796 | 1 1797 | 40 1798 | 1 1799 | 40 1800 | 1 1801 | 10 1802 | 52.787511 1803 | 20 1804 | 64.455138 1805 | 30 1806 | 0.0 1807 | 10 1808 | 52.787499 1809 | 20 1810 | 64.560411 1811 | 30 1812 | 0.0 1813 | 10 1814 | 52.829313 1815 | 20 1816 | 64.661375 1817 | 30 1818 | 0.0 1819 | 10 1820 | 52.903753 1821 | 20 1822 | 64.735815 1823 | 30 1824 | 0.0 1825 | 0 1826 | SPLINE 1827 | 5 1828 | 115 1829 | 100 1830 | AcDbEntity 1831 | 8 1832 | Layer_1 1833 | 62 1834 | 7 1835 | 100 1836 | AcDbSpline 1837 | 70 1838 | 8 1839 | 71 1840 | 3 1841 | 72 1842 | 8 1843 | 73 1844 | 4 1845 | 74 1846 | 0 1847 | 40 1848 | 0 1849 | 40 1850 | 0 1851 | 40 1852 | 0 1853 | 40 1854 | 0 1855 | 40 1856 | 1 1857 | 40 1858 | 1 1859 | 40 1860 | 1 1861 | 40 1862 | 1 1863 | 10 1864 | 52.903753 1865 | 20 1866 | 64.735815 1867 | 30 1868 | 0.0 1869 | 10 1870 | 52.978192 1871 | 20 1872 | 64.810254 1873 | 30 1874 | 0.0 1875 | 10 1876 | 53.079157 1877 | 20 1878 | 64.852068 1879 | 30 1880 | 0.0 1881 | 10 1882 | 53.184430 1883 | 20 1884 | 64.852057 1885 | 30 1886 | 0.0 1887 | 0 1888 | LWPOLYLINE 1889 | 5 1890 | 116 1891 | 100 1892 | AcDbEntity 1893 | 8 1894 | Layer_1 1895 | 62 1896 | 7 1897 | 100 1898 | AcDbPolyline 1899 | 90 1900 | 3 1901 | 70 1902 | 0 1903 | 10 1904 | 68.816043 1905 | 20 1906 | 65.381191 1907 | 30 1908 | 0.0 1909 | 10 1910 | 52.898670 1911 | 20 1912 | 65.381191 1913 | 30 1914 | 0.0 1915 | 10 1916 | 52.898670 1917 | 20 1918 | 65.381191 1919 | 30 1920 | 0.0 1921 | 0 1922 | SPLINE 1923 | 5 1924 | 117 1925 | 100 1926 | AcDbEntity 1927 | 8 1928 | Layer_1 1929 | 62 1930 | 7 1931 | 100 1932 | AcDbSpline 1933 | 70 1934 | 8 1935 | 71 1936 | 3 1937 | 72 1938 | 8 1939 | 73 1940 | 4 1941 | 74 1942 | 0 1943 | 40 1944 | 0 1945 | 40 1946 | 0 1947 | 40 1948 | 0 1949 | 40 1950 | 0 1951 | 40 1952 | 1 1953 | 40 1954 | 1 1955 | 40 1956 | 1 1957 | 40 1958 | 1 1959 | 10 1960 | 68.530420 1961 | 20 1962 | 64.852057 1963 | 30 1964 | 0.0 1965 | 10 1966 | 68.749589 1967 | 20 1968 | 64.852006 1969 | 30 1970 | 0.0 1971 | 10 1972 | 68.927227 1973 | 20 1974 | 64.674307 1975 | 30 1976 | 0.0 1977 | 10 1978 | 68.927202 1979 | 20 1980 | 64.455138 1981 | 30 1982 | 0.0 1983 | 0 1984 | SPLINE 1985 | 5 1986 | 118 1987 | 100 1988 | AcDbEntity 1989 | 8 1990 | Layer_1 1991 | 62 1992 | 7 1993 | 100 1994 | AcDbSpline 1995 | 70 1996 | 8 1997 | 71 1998 | 3 1999 | 72 2000 | 8 2001 | 73 2002 | 4 2003 | 74 2004 | 0 2005 | 40 2006 | 0 2007 | 40 2008 | 0 2009 | 40 2010 | 0 2011 | 40 2012 | 0 2013 | 40 2014 | 1 2015 | 40 2016 | 1 2017 | 40 2018 | 1 2019 | 40 2020 | 1 2021 | 10 2022 | 68.927202 2023 | 20 2024 | 64.455138 2025 | 30 2026 | 0.0 2027 | 10 2028 | 68.927227 2029 | 20 2030 | 64.235969 2031 | 30 2032 | 0.0 2033 | 10 2034 | 68.749589 2035 | 20 2036 | 64.058270 2037 | 30 2038 | 0.0 2039 | 10 2040 | 68.530420 2041 | 20 2042 | 64.058219 2043 | 30 2044 | 0.0 2045 | 0 2046 | SPLINE 2047 | 5 2048 | 119 2049 | 100 2050 | AcDbEntity 2051 | 8 2052 | Layer_1 2053 | 62 2054 | 7 2055 | 100 2056 | AcDbSpline 2057 | 70 2058 | 8 2059 | 71 2060 | 3 2061 | 72 2062 | 8 2063 | 73 2064 | 4 2065 | 74 2066 | 0 2067 | 40 2068 | 0 2069 | 40 2070 | 0 2071 | 40 2072 | 0 2073 | 40 2074 | 0 2075 | 40 2076 | 1 2077 | 40 2078 | 1 2079 | 40 2080 | 1 2081 | 40 2082 | 1 2083 | 10 2084 | 68.530420 2085 | 20 2086 | 64.058219 2087 | 30 2088 | 0.0 2089 | 10 2090 | 68.425147 2091 | 20 2092 | 64.058207 2093 | 30 2094 | 0.0 2095 | 10 2096 | 68.324182 2097 | 20 2098 | 64.100021 2099 | 30 2100 | 0.0 2101 | 10 2102 | 68.249743 2103 | 20 2104 | 64.174461 2105 | 30 2106 | 0.0 2107 | 0 2108 | SPLINE 2109 | 5 2110 | 11a 2111 | 100 2112 | AcDbEntity 2113 | 8 2114 | Layer_1 2115 | 62 2116 | 7 2117 | 100 2118 | AcDbSpline 2119 | 70 2120 | 8 2121 | 71 2122 | 3 2123 | 72 2124 | 8 2125 | 73 2126 | 4 2127 | 74 2128 | 0 2129 | 40 2130 | 0 2131 | 40 2132 | 0 2133 | 40 2134 | 0 2135 | 40 2136 | 0 2137 | 40 2138 | 1 2139 | 40 2140 | 1 2141 | 40 2142 | 1 2143 | 40 2144 | 1 2145 | 10 2146 | 68.249743 2147 | 20 2148 | 64.174461 2149 | 30 2150 | 0.0 2151 | 10 2152 | 68.175303 2153 | 20 2154 | 64.248900 2155 | 30 2156 | 0.0 2157 | 10 2158 | 68.133489 2159 | 20 2160 | 64.349865 2161 | 30 2162 | 0.0 2163 | 10 2164 | 68.133501 2165 | 20 2166 | 64.455138 2167 | 30 2168 | 0.0 2169 | 0 2170 | SPLINE 2171 | 5 2172 | 11b 2173 | 100 2174 | AcDbEntity 2175 | 8 2176 | Layer_1 2177 | 62 2178 | 7 2179 | 100 2180 | AcDbSpline 2181 | 70 2182 | 8 2183 | 71 2184 | 3 2185 | 72 2186 | 8 2187 | 73 2188 | 4 2189 | 74 2190 | 0 2191 | 40 2192 | 0 2193 | 40 2194 | 0 2195 | 40 2196 | 0 2197 | 40 2198 | 0 2199 | 40 2200 | 1 2201 | 40 2202 | 1 2203 | 40 2204 | 1 2205 | 40 2206 | 1 2207 | 10 2208 | 68.133501 2209 | 20 2210 | 64.455138 2211 | 30 2212 | 0.0 2213 | 10 2214 | 68.133489 2215 | 20 2216 | 64.560411 2217 | 30 2218 | 0.0 2219 | 10 2220 | 68.175303 2221 | 20 2222 | 64.661375 2223 | 30 2224 | 0.0 2225 | 10 2226 | 68.249743 2227 | 20 2228 | 64.735815 2229 | 30 2230 | 0.0 2231 | 0 2232 | SPLINE 2233 | 5 2234 | 11c 2235 | 100 2236 | AcDbEntity 2237 | 8 2238 | Layer_1 2239 | 62 2240 | 7 2241 | 100 2242 | AcDbSpline 2243 | 70 2244 | 8 2245 | 71 2246 | 3 2247 | 72 2248 | 8 2249 | 73 2250 | 4 2251 | 74 2252 | 0 2253 | 40 2254 | 0 2255 | 40 2256 | 0 2257 | 40 2258 | 0 2259 | 40 2260 | 0 2261 | 40 2262 | 1 2263 | 40 2264 | 1 2265 | 40 2266 | 1 2267 | 40 2268 | 1 2269 | 10 2270 | 68.249743 2271 | 20 2272 | 64.735815 2273 | 30 2274 | 0.0 2275 | 10 2276 | 68.324182 2277 | 20 2278 | 64.810254 2279 | 30 2280 | 0.0 2281 | 10 2282 | 68.425147 2283 | 20 2284 | 64.852068 2285 | 30 2286 | 0.0 2287 | 10 2288 | 68.530420 2289 | 20 2290 | 64.852057 2291 | 30 2292 | 0.0 2293 | 0 2294 | LWPOLYLINE 2295 | 5 2296 | 11d 2297 | 100 2298 | AcDbEntity 2299 | 8 2300 | Layer_1 2301 | 62 2302 | 7 2303 | 100 2304 | AcDbPolyline 2305 | 90 2306 | 1 2307 | 70 2308 | 1 2309 | 10 2310 | 53.184430 2311 | 20 2312 | 64.852057 2313 | 30 2314 | 0.0 2315 | 0 2316 | LWPOLYLINE 2317 | 5 2318 | 11e 2319 | 100 2320 | AcDbEntity 2321 | 8 2322 | Layer_1 2323 | 62 2324 | 7 2325 | 100 2326 | AcDbPolyline 2327 | 90 2328 | 1 2329 | 70 2330 | 1 2331 | 10 2332 | 68.530420 2333 | 20 2334 | 64.852057 2335 | 30 2336 | 0.0 2337 | 0 2338 | SPLINE 2339 | 5 2340 | 11f 2341 | 100 2342 | AcDbEntity 2343 | 8 2344 | Layer_1 2345 | 62 2346 | 7 2347 | 100 2348 | AcDbSpline 2349 | 70 2350 | 8 2351 | 71 2352 | 3 2353 | 72 2354 | 8 2355 | 73 2356 | 4 2357 | 74 2358 | 0 2359 | 40 2360 | 0 2361 | 40 2362 | 0 2363 | 40 2364 | 0 2365 | 40 2366 | 0 2367 | 40 2368 | 1 2369 | 40 2370 | 1 2371 | 40 2372 | 1 2373 | 40 2374 | 1 2375 | 10 2376 | 57.101356 2377 | 20 2378 | 61.740990 2379 | 30 2380 | 0.0 2381 | 10 2382 | 57.174646 2383 | 20 2384 | 61.740990 2385 | 30 2386 | 0.0 2387 | 10 2388 | 57.233648 2389 | 20 2390 | 61.681988 2391 | 30 2392 | 0.0 2393 | 10 2394 | 57.233648 2395 | 20 2396 | 61.608698 2397 | 30 2398 | 0.0 2399 | 0 2400 | LWPOLYLINE 2401 | 5 2402 | 120 2403 | 100 2404 | AcDbEntity 2405 | 8 2406 | Layer_1 2407 | 62 2408 | 7 2409 | 100 2410 | AcDbPolyline 2411 | 90 2412 | 2 2413 | 70 2414 | 0 2415 | 10 2416 | 55.527347 2417 | 20 2418 | 61.740990 2419 | 30 2420 | 0.0 2421 | 10 2422 | 57.101356 2423 | 20 2424 | 61.740990 2425 | 30 2426 | 0.0 2427 | 0 2428 | SPLINE 2429 | 5 2430 | 121 2431 | 100 2432 | AcDbEntity 2433 | 8 2434 | Layer_1 2435 | 62 2436 | 7 2437 | 100 2438 | AcDbSpline 2439 | 70 2440 | 8 2441 | 71 2442 | 3 2443 | 72 2444 | 8 2445 | 73 2446 | 4 2447 | 74 2448 | 0 2449 | 40 2450 | 0 2451 | 40 2452 | 0 2453 | 40 2454 | 0 2455 | 40 2456 | 0 2457 | 40 2458 | 1 2459 | 40 2460 | 1 2461 | 40 2462 | 1 2463 | 40 2464 | 1 2465 | 10 2466 | 57.233648 2467 | 20 2468 | 60.883271 2469 | 30 2470 | 0.0 2471 | 10 2472 | 57.233648 2473 | 20 2474 | 60.809981 2475 | 30 2476 | 0.0 2477 | 10 2478 | 57.174646 2479 | 20 2480 | 60.750979 2481 | 30 2482 | 0.0 2483 | 10 2484 | 57.101356 2485 | 20 2486 | 60.750979 2487 | 30 2488 | 0.0 2489 | 0 2490 | LWPOLYLINE 2491 | 5 2492 | 122 2493 | 100 2494 | AcDbEntity 2495 | 8 2496 | Layer_1 2497 | 62 2498 | 7 2499 | 100 2500 | AcDbPolyline 2501 | 90 2502 | 2 2503 | 70 2504 | 0 2505 | 10 2506 | 57.233648 2507 | 20 2508 | 61.608698 2509 | 30 2510 | 0.0 2511 | 10 2512 | 57.233648 2513 | 20 2514 | 60.883271 2515 | 30 2516 | 0.0 2517 | 0 2518 | SPLINE 2519 | 5 2520 | 123 2521 | 100 2522 | AcDbEntity 2523 | 8 2524 | Layer_1 2525 | 62 2526 | 7 2527 | 100 2528 | AcDbSpline 2529 | 70 2530 | 8 2531 | 71 2532 | 3 2533 | 72 2534 | 8 2535 | 73 2536 | 4 2537 | 74 2538 | 0 2539 | 40 2540 | 0 2541 | 40 2542 | 0 2543 | 40 2544 | 0 2545 | 40 2546 | 0 2547 | 40 2548 | 1 2549 | 40 2550 | 1 2551 | 40 2552 | 1 2553 | 40 2554 | 1 2555 | 10 2556 | 55.527347 2557 | 20 2558 | 60.750979 2559 | 30 2560 | 0.0 2561 | 10 2562 | 55.454058 2563 | 20 2564 | 60.750979 2565 | 30 2566 | 0.0 2567 | 10 2568 | 55.395056 2569 | 20 2570 | 60.809981 2571 | 30 2572 | 0.0 2573 | 10 2574 | 55.395056 2575 | 20 2576 | 60.883271 2577 | 30 2578 | 0.0 2579 | 0 2580 | LWPOLYLINE 2581 | 5 2582 | 124 2583 | 100 2584 | AcDbEntity 2585 | 8 2586 | Layer_1 2587 | 62 2588 | 7 2589 | 100 2590 | AcDbPolyline 2591 | 90 2592 | 2 2593 | 70 2594 | 0 2595 | 10 2596 | 57.101356 2597 | 20 2598 | 60.750979 2599 | 30 2600 | 0.0 2601 | 10 2602 | 55.527347 2603 | 20 2604 | 60.750979 2605 | 30 2606 | 0.0 2607 | 0 2608 | SPLINE 2609 | 5 2610 | 125 2611 | 100 2612 | AcDbEntity 2613 | 8 2614 | Layer_1 2615 | 62 2616 | 7 2617 | 100 2618 | AcDbSpline 2619 | 70 2620 | 8 2621 | 71 2622 | 3 2623 | 72 2624 | 8 2625 | 73 2626 | 4 2627 | 74 2628 | 0 2629 | 40 2630 | 0 2631 | 40 2632 | 0 2633 | 40 2634 | 0 2635 | 40 2636 | 0 2637 | 40 2638 | 1 2639 | 40 2640 | 1 2641 | 40 2642 | 1 2643 | 40 2644 | 1 2645 | 10 2646 | 55.395056 2647 | 20 2648 | 61.608698 2649 | 30 2650 | 0.0 2651 | 10 2652 | 55.395056 2653 | 20 2654 | 61.681988 2655 | 30 2656 | 0.0 2657 | 10 2658 | 55.454058 2659 | 20 2660 | 61.740990 2661 | 30 2662 | 0.0 2663 | 10 2664 | 55.527347 2665 | 20 2666 | 61.740990 2667 | 30 2668 | 0.0 2669 | 0 2670 | LWPOLYLINE 2671 | 5 2672 | 126 2673 | 100 2674 | AcDbEntity 2675 | 8 2676 | Layer_1 2677 | 62 2678 | 7 2679 | 100 2680 | AcDbPolyline 2681 | 90 2682 | 2 2683 | 70 2684 | 0 2685 | 10 2686 | 55.395056 2687 | 20 2688 | 60.883271 2689 | 30 2690 | 0.0 2691 | 10 2692 | 55.395056 2693 | 20 2694 | 61.608698 2695 | 30 2696 | 0.0 2697 | 0 2698 | LWPOLYLINE 2699 | 5 2700 | 127 2701 | 100 2702 | AcDbEntity 2703 | 8 2704 | Layer_1 2705 | 62 2706 | 7 2707 | 100 2708 | AcDbPolyline 2709 | 90 2710 | 1 2711 | 70 2712 | 1 2713 | 10 2714 | 55.527347 2715 | 20 2716 | 61.740990 2717 | 30 2718 | 0.0 2719 | 0 2720 | SPLINE 2721 | 5 2722 | 128 2723 | 100 2724 | AcDbEntity 2725 | 8 2726 | Layer_1 2727 | 62 2728 | 7 2729 | 100 2730 | AcDbSpline 2731 | 70 2732 | 8 2733 | 71 2734 | 3 2735 | 72 2736 | 8 2737 | 73 2738 | 4 2739 | 74 2740 | 0 2741 | 40 2742 | 0 2743 | 40 2744 | 0 2745 | 40 2746 | 0 2747 | 40 2748 | 0 2749 | 40 2750 | 1 2751 | 40 2752 | 1 2753 | 40 2754 | 1 2755 | 40 2756 | 1 2757 | 10 2758 | 63.191549 2759 | 20 2760 | 61.740990 2761 | 30 2762 | 0.0 2763 | 10 2764 | 63.264838 2765 | 20 2766 | 61.740990 2767 | 30 2768 | 0.0 2769 | 10 2770 | 63.323840 2771 | 20 2772 | 61.681988 2773 | 30 2774 | 0.0 2775 | 10 2776 | 63.323840 2777 | 20 2778 | 61.608698 2779 | 30 2780 | 0.0 2781 | 0 2782 | LWPOLYLINE 2783 | 5 2784 | 129 2785 | 100 2786 | AcDbEntity 2787 | 8 2788 | Layer_1 2789 | 62 2790 | 7 2791 | 100 2792 | AcDbPolyline 2793 | 90 2794 | 2 2795 | 70 2796 | 0 2797 | 10 2798 | 61.617540 2799 | 20 2800 | 61.740990 2801 | 30 2802 | 0.0 2803 | 10 2804 | 63.191549 2805 | 20 2806 | 61.740990 2807 | 30 2808 | 0.0 2809 | 0 2810 | SPLINE 2811 | 5 2812 | 12a 2813 | 100 2814 | AcDbEntity 2815 | 8 2816 | Layer_1 2817 | 62 2818 | 7 2819 | 100 2820 | AcDbSpline 2821 | 70 2822 | 8 2823 | 71 2824 | 3 2825 | 72 2826 | 8 2827 | 73 2828 | 4 2829 | 74 2830 | 0 2831 | 40 2832 | 0 2833 | 40 2834 | 0 2835 | 40 2836 | 0 2837 | 40 2838 | 0 2839 | 40 2840 | 1 2841 | 40 2842 | 1 2843 | 40 2844 | 1 2845 | 40 2846 | 1 2847 | 10 2848 | 63.323840 2849 | 20 2850 | 60.883271 2851 | 30 2852 | 0.0 2853 | 10 2854 | 63.323840 2855 | 20 2856 | 60.809981 2857 | 30 2858 | 0.0 2859 | 10 2860 | 63.264838 2861 | 20 2862 | 60.750979 2863 | 30 2864 | 0.0 2865 | 10 2866 | 63.191549 2867 | 20 2868 | 60.750979 2869 | 30 2870 | 0.0 2871 | 0 2872 | LWPOLYLINE 2873 | 5 2874 | 12b 2875 | 100 2876 | AcDbEntity 2877 | 8 2878 | Layer_1 2879 | 62 2880 | 7 2881 | 100 2882 | AcDbPolyline 2883 | 90 2884 | 2 2885 | 70 2886 | 0 2887 | 10 2888 | 63.323840 2889 | 20 2890 | 61.608698 2891 | 30 2892 | 0.0 2893 | 10 2894 | 63.323840 2895 | 20 2896 | 60.883271 2897 | 30 2898 | 0.0 2899 | 0 2900 | SPLINE 2901 | 5 2902 | 12c 2903 | 100 2904 | AcDbEntity 2905 | 8 2906 | Layer_1 2907 | 62 2908 | 7 2909 | 100 2910 | AcDbSpline 2911 | 70 2912 | 8 2913 | 71 2914 | 3 2915 | 72 2916 | 8 2917 | 73 2918 | 4 2919 | 74 2920 | 0 2921 | 40 2922 | 0 2923 | 40 2924 | 0 2925 | 40 2926 | 0 2927 | 40 2928 | 0 2929 | 40 2930 | 1 2931 | 40 2932 | 1 2933 | 40 2934 | 1 2935 | 40 2936 | 1 2937 | 10 2938 | 61.617540 2939 | 20 2940 | 60.750979 2941 | 30 2942 | 0.0 2943 | 10 2944 | 61.544250 2945 | 20 2946 | 60.750979 2947 | 30 2948 | 0.0 2949 | 10 2950 | 61.485248 2951 | 20 2952 | 60.809981 2953 | 30 2954 | 0.0 2955 | 10 2956 | 61.485248 2957 | 20 2958 | 60.883271 2959 | 30 2960 | 0.0 2961 | 0 2962 | LWPOLYLINE 2963 | 5 2964 | 12d 2965 | 100 2966 | AcDbEntity 2967 | 8 2968 | Layer_1 2969 | 62 2970 | 7 2971 | 100 2972 | AcDbPolyline 2973 | 90 2974 | 2 2975 | 70 2976 | 0 2977 | 10 2978 | 63.191549 2979 | 20 2980 | 60.750979 2981 | 30 2982 | 0.0 2983 | 10 2984 | 61.617540 2985 | 20 2986 | 60.750979 2987 | 30 2988 | 0.0 2989 | 0 2990 | SPLINE 2991 | 5 2992 | 12e 2993 | 100 2994 | AcDbEntity 2995 | 8 2996 | Layer_1 2997 | 62 2998 | 7 2999 | 100 3000 | AcDbSpline 3001 | 70 3002 | 8 3003 | 71 3004 | 3 3005 | 72 3006 | 8 3007 | 73 3008 | 4 3009 | 74 3010 | 0 3011 | 40 3012 | 0 3013 | 40 3014 | 0 3015 | 40 3016 | 0 3017 | 40 3018 | 0 3019 | 40 3020 | 1 3021 | 40 3022 | 1 3023 | 40 3024 | 1 3025 | 40 3026 | 1 3027 | 10 3028 | 61.485248 3029 | 20 3030 | 61.608698 3031 | 30 3032 | 0.0 3033 | 10 3034 | 61.485248 3035 | 20 3036 | 61.681988 3037 | 30 3038 | 0.0 3039 | 10 3040 | 61.544250 3041 | 20 3042 | 61.740990 3043 | 30 3044 | 0.0 3045 | 10 3046 | 61.617540 3047 | 20 3048 | 61.740990 3049 | 30 3050 | 0.0 3051 | 0 3052 | LWPOLYLINE 3053 | 5 3054 | 12f 3055 | 100 3056 | AcDbEntity 3057 | 8 3058 | Layer_1 3059 | 62 3060 | 7 3061 | 100 3062 | AcDbPolyline 3063 | 90 3064 | 2 3065 | 70 3066 | 0 3067 | 10 3068 | 61.485248 3069 | 20 3070 | 60.883271 3071 | 30 3072 | 0.0 3073 | 10 3074 | 61.485248 3075 | 20 3076 | 61.608698 3077 | 30 3078 | 0.0 3079 | 0 3080 | LWPOLYLINE 3081 | 5 3082 | 130 3083 | 100 3084 | AcDbEntity 3085 | 8 3086 | Layer_1 3087 | 62 3088 | 7 3089 | 100 3090 | AcDbPolyline 3091 | 90 3092 | 1 3093 | 70 3094 | 1 3095 | 10 3096 | 61.617540 3097 | 20 3098 | 61.740990 3099 | 30 3100 | 0.0 3101 | 0 3102 | SPLINE 3103 | 5 3104 | 131 3105 | 100 3106 | AcDbEntity 3107 | 8 3108 | Layer_1 3109 | 62 3110 | 7 3111 | 100 3112 | AcDbSpline 3113 | 70 3114 | 8 3115 | 71 3116 | 3 3117 | 72 3118 | 8 3119 | 73 3120 | 4 3121 | 74 3122 | 0 3123 | 40 3124 | 0 3125 | 40 3126 | 0 3127 | 40 3128 | 0 3129 | 40 3130 | 0 3131 | 40 3132 | 1 3133 | 40 3134 | 1 3135 | 40 3136 | 1 3137 | 40 3138 | 1 3139 | 10 3140 | 60.146451 3141 | 20 3142 | 61.740990 3143 | 30 3144 | 0.0 3145 | 10 3146 | 60.219741 3147 | 20 3148 | 61.740990 3149 | 30 3150 | 0.0 3151 | 10 3152 | 60.278743 3153 | 20 3154 | 61.681988 3155 | 30 3156 | 0.0 3157 | 10 3158 | 60.278743 3159 | 20 3160 | 61.608698 3161 | 30 3162 | 0.0 3163 | 0 3164 | LWPOLYLINE 3165 | 5 3166 | 132 3167 | 100 3168 | AcDbEntity 3169 | 8 3170 | Layer_1 3171 | 62 3172 | 7 3173 | 100 3174 | AcDbPolyline 3175 | 90 3176 | 2 3177 | 70 3178 | 0 3179 | 10 3180 | 58.572442 3181 | 20 3182 | 61.740990 3183 | 30 3184 | 0.0 3185 | 10 3186 | 60.146451 3187 | 20 3188 | 61.740990 3189 | 30 3190 | 0.0 3191 | 0 3192 | SPLINE 3193 | 5 3194 | 133 3195 | 100 3196 | AcDbEntity 3197 | 8 3198 | Layer_1 3199 | 62 3200 | 7 3201 | 100 3202 | AcDbSpline 3203 | 70 3204 | 8 3205 | 71 3206 | 3 3207 | 72 3208 | 8 3209 | 73 3210 | 4 3211 | 74 3212 | 0 3213 | 40 3214 | 0 3215 | 40 3216 | 0 3217 | 40 3218 | 0 3219 | 40 3220 | 0 3221 | 40 3222 | 1 3223 | 40 3224 | 1 3225 | 40 3226 | 1 3227 | 40 3228 | 1 3229 | 10 3230 | 60.278743 3231 | 20 3232 | 60.883271 3233 | 30 3234 | 0.0 3235 | 10 3236 | 60.278743 3237 | 20 3238 | 60.809981 3239 | 30 3240 | 0.0 3241 | 10 3242 | 60.219741 3243 | 20 3244 | 60.750979 3245 | 30 3246 | 0.0 3247 | 10 3248 | 60.146451 3249 | 20 3250 | 60.750979 3251 | 30 3252 | 0.0 3253 | 0 3254 | LWPOLYLINE 3255 | 5 3256 | 134 3257 | 100 3258 | AcDbEntity 3259 | 8 3260 | Layer_1 3261 | 62 3262 | 7 3263 | 100 3264 | AcDbPolyline 3265 | 90 3266 | 2 3267 | 70 3268 | 0 3269 | 10 3270 | 60.278743 3271 | 20 3272 | 61.608698 3273 | 30 3274 | 0.0 3275 | 10 3276 | 60.278743 3277 | 20 3278 | 60.883271 3279 | 30 3280 | 0.0 3281 | 0 3282 | SPLINE 3283 | 5 3284 | 135 3285 | 100 3286 | AcDbEntity 3287 | 8 3288 | Layer_1 3289 | 62 3290 | 7 3291 | 100 3292 | AcDbSpline 3293 | 70 3294 | 8 3295 | 71 3296 | 3 3297 | 72 3298 | 8 3299 | 73 3300 | 4 3301 | 74 3302 | 0 3303 | 40 3304 | 0 3305 | 40 3306 | 0 3307 | 40 3308 | 0 3309 | 40 3310 | 0 3311 | 40 3312 | 1 3313 | 40 3314 | 1 3315 | 40 3316 | 1 3317 | 40 3318 | 1 3319 | 10 3320 | 58.572442 3321 | 20 3322 | 60.750979 3323 | 30 3324 | 0.0 3325 | 10 3326 | 58.499153 3327 | 20 3328 | 60.750979 3329 | 30 3330 | 0.0 3331 | 10 3332 | 58.440151 3333 | 20 3334 | 60.809981 3335 | 30 3336 | 0.0 3337 | 10 3338 | 58.440151 3339 | 20 3340 | 60.883271 3341 | 30 3342 | 0.0 3343 | 0 3344 | LWPOLYLINE 3345 | 5 3346 | 136 3347 | 100 3348 | AcDbEntity 3349 | 8 3350 | Layer_1 3351 | 62 3352 | 7 3353 | 100 3354 | AcDbPolyline 3355 | 90 3356 | 2 3357 | 70 3358 | 0 3359 | 10 3360 | 60.146451 3361 | 20 3362 | 60.750979 3363 | 30 3364 | 0.0 3365 | 10 3366 | 58.572442 3367 | 20 3368 | 60.750979 3369 | 30 3370 | 0.0 3371 | 0 3372 | SPLINE 3373 | 5 3374 | 137 3375 | 100 3376 | AcDbEntity 3377 | 8 3378 | Layer_1 3379 | 62 3380 | 7 3381 | 100 3382 | AcDbSpline 3383 | 70 3384 | 8 3385 | 71 3386 | 3 3387 | 72 3388 | 8 3389 | 73 3390 | 4 3391 | 74 3392 | 0 3393 | 40 3394 | 0 3395 | 40 3396 | 0 3397 | 40 3398 | 0 3399 | 40 3400 | 0 3401 | 40 3402 | 1 3403 | 40 3404 | 1 3405 | 40 3406 | 1 3407 | 40 3408 | 1 3409 | 10 3410 | 58.440151 3411 | 20 3412 | 61.608698 3413 | 30 3414 | 0.0 3415 | 10 3416 | 58.440151 3417 | 20 3418 | 61.681988 3419 | 30 3420 | 0.0 3421 | 10 3422 | 58.499153 3423 | 20 3424 | 61.740990 3425 | 30 3426 | 0.0 3427 | 10 3428 | 58.572442 3429 | 20 3430 | 61.740990 3431 | 30 3432 | 0.0 3433 | 0 3434 | LWPOLYLINE 3435 | 5 3436 | 138 3437 | 100 3438 | AcDbEntity 3439 | 8 3440 | Layer_1 3441 | 62 3442 | 7 3443 | 100 3444 | AcDbPolyline 3445 | 90 3446 | 2 3447 | 70 3448 | 0 3449 | 10 3450 | 58.440151 3451 | 20 3452 | 60.883271 3453 | 30 3454 | 0.0 3455 | 10 3456 | 58.440151 3457 | 20 3458 | 61.608698 3459 | 30 3460 | 0.0 3461 | 0 3462 | LWPOLYLINE 3463 | 5 3464 | 139 3465 | 100 3466 | AcDbEntity 3467 | 8 3468 | Layer_1 3469 | 62 3470 | 7 3471 | 100 3472 | AcDbPolyline 3473 | 90 3474 | 1 3475 | 70 3476 | 1 3477 | 10 3478 | 58.572442 3479 | 20 3480 | 61.740990 3481 | 30 3482 | 0.0 3483 | 0 3484 | SPLINE 3485 | 5 3486 | 13a 3487 | 100 3488 | AcDbEntity 3489 | 8 3490 | Layer_1 3491 | 62 3492 | 7 3493 | 100 3494 | AcDbSpline 3495 | 70 3496 | 8 3497 | 71 3498 | 3 3499 | 72 3500 | 8 3501 | 73 3502 | 4 3503 | 74 3504 | 0 3505 | 40 3506 | 0 3507 | 40 3508 | 0 3509 | 40 3510 | 0 3511 | 40 3512 | 0 3513 | 40 3514 | 1 3515 | 40 3516 | 1 3517 | 40 3518 | 1 3519 | 40 3520 | 1 3521 | 10 3522 | 66.236644 3523 | 20 3524 | 61.740990 3525 | 30 3526 | 0.0 3527 | 10 3528 | 66.309933 3529 | 20 3530 | 61.740990 3531 | 30 3532 | 0.0 3533 | 10 3534 | 66.368935 3535 | 20 3536 | 61.681988 3537 | 30 3538 | 0.0 3539 | 10 3540 | 66.368935 3541 | 20 3542 | 61.608698 3543 | 30 3544 | 0.0 3545 | 0 3546 | LWPOLYLINE 3547 | 5 3548 | 13b 3549 | 100 3550 | AcDbEntity 3551 | 8 3552 | Layer_1 3553 | 62 3554 | 7 3555 | 100 3556 | AcDbPolyline 3557 | 90 3558 | 2 3559 | 70 3560 | 0 3561 | 10 3562 | 64.662635 3563 | 20 3564 | 61.740990 3565 | 30 3566 | 0.0 3567 | 10 3568 | 66.236644 3569 | 20 3570 | 61.740990 3571 | 30 3572 | 0.0 3573 | 0 3574 | SPLINE 3575 | 5 3576 | 13c 3577 | 100 3578 | AcDbEntity 3579 | 8 3580 | Layer_1 3581 | 62 3582 | 7 3583 | 100 3584 | AcDbSpline 3585 | 70 3586 | 8 3587 | 71 3588 | 3 3589 | 72 3590 | 8 3591 | 73 3592 | 4 3593 | 74 3594 | 0 3595 | 40 3596 | 0 3597 | 40 3598 | 0 3599 | 40 3600 | 0 3601 | 40 3602 | 0 3603 | 40 3604 | 1 3605 | 40 3606 | 1 3607 | 40 3608 | 1 3609 | 40 3610 | 1 3611 | 10 3612 | 66.368935 3613 | 20 3614 | 60.883271 3615 | 30 3616 | 0.0 3617 | 10 3618 | 66.368935 3619 | 20 3620 | 60.809981 3621 | 30 3622 | 0.0 3623 | 10 3624 | 66.309933 3625 | 20 3626 | 60.750979 3627 | 30 3628 | 0.0 3629 | 10 3630 | 66.236644 3631 | 20 3632 | 60.750979 3633 | 30 3634 | 0.0 3635 | 0 3636 | LWPOLYLINE 3637 | 5 3638 | 13d 3639 | 100 3640 | AcDbEntity 3641 | 8 3642 | Layer_1 3643 | 62 3644 | 7 3645 | 100 3646 | AcDbPolyline 3647 | 90 3648 | 2 3649 | 70 3650 | 0 3651 | 10 3652 | 66.368935 3653 | 20 3654 | 61.608698 3655 | 30 3656 | 0.0 3657 | 10 3658 | 66.368935 3659 | 20 3660 | 60.883271 3661 | 30 3662 | 0.0 3663 | 0 3664 | SPLINE 3665 | 5 3666 | 13e 3667 | 100 3668 | AcDbEntity 3669 | 8 3670 | Layer_1 3671 | 62 3672 | 7 3673 | 100 3674 | AcDbSpline 3675 | 70 3676 | 8 3677 | 71 3678 | 3 3679 | 72 3680 | 8 3681 | 73 3682 | 4 3683 | 74 3684 | 0 3685 | 40 3686 | 0 3687 | 40 3688 | 0 3689 | 40 3690 | 0 3691 | 40 3692 | 0 3693 | 40 3694 | 1 3695 | 40 3696 | 1 3697 | 40 3698 | 1 3699 | 40 3700 | 1 3701 | 10 3702 | 64.662635 3703 | 20 3704 | 60.750979 3705 | 30 3706 | 0.0 3707 | 10 3708 | 64.589345 3709 | 20 3710 | 60.750979 3711 | 30 3712 | 0.0 3713 | 10 3714 | 64.530343 3715 | 20 3716 | 60.809981 3717 | 30 3718 | 0.0 3719 | 10 3720 | 64.530343 3721 | 20 3722 | 60.883271 3723 | 30 3724 | 0.0 3725 | 0 3726 | LWPOLYLINE 3727 | 5 3728 | 13f 3729 | 100 3730 | AcDbEntity 3731 | 8 3732 | Layer_1 3733 | 62 3734 | 7 3735 | 100 3736 | AcDbPolyline 3737 | 90 3738 | 2 3739 | 70 3740 | 0 3741 | 10 3742 | 66.236644 3743 | 20 3744 | 60.750979 3745 | 30 3746 | 0.0 3747 | 10 3748 | 64.662635 3749 | 20 3750 | 60.750979 3751 | 30 3752 | 0.0 3753 | 0 3754 | SPLINE 3755 | 5 3756 | 140 3757 | 100 3758 | AcDbEntity 3759 | 8 3760 | Layer_1 3761 | 62 3762 | 7 3763 | 100 3764 | AcDbSpline 3765 | 70 3766 | 8 3767 | 71 3768 | 3 3769 | 72 3770 | 8 3771 | 73 3772 | 4 3773 | 74 3774 | 0 3775 | 40 3776 | 0 3777 | 40 3778 | 0 3779 | 40 3780 | 0 3781 | 40 3782 | 0 3783 | 40 3784 | 1 3785 | 40 3786 | 1 3787 | 40 3788 | 1 3789 | 40 3790 | 1 3791 | 10 3792 | 64.530343 3793 | 20 3794 | 61.608698 3795 | 30 3796 | 0.0 3797 | 10 3798 | 64.530343 3799 | 20 3800 | 61.681988 3801 | 30 3802 | 0.0 3803 | 10 3804 | 64.589345 3805 | 20 3806 | 61.740990 3807 | 30 3808 | 0.0 3809 | 10 3810 | 64.662635 3811 | 20 3812 | 61.740990 3813 | 30 3814 | 0.0 3815 | 0 3816 | LWPOLYLINE 3817 | 5 3818 | 141 3819 | 100 3820 | AcDbEntity 3821 | 8 3822 | Layer_1 3823 | 62 3824 | 7 3825 | 100 3826 | AcDbPolyline 3827 | 90 3828 | 2 3829 | 70 3830 | 0 3831 | 10 3832 | 64.530343 3833 | 20 3834 | 60.883271 3835 | 30 3836 | 0.0 3837 | 10 3838 | 64.530343 3839 | 20 3840 | 61.608698 3841 | 30 3842 | 0.0 3843 | 0 3844 | LWPOLYLINE 3845 | 5 3846 | 142 3847 | 100 3848 | AcDbEntity 3849 | 8 3850 | Layer_1 3851 | 62 3852 | 7 3853 | 100 3854 | AcDbPolyline 3855 | 90 3856 | 1 3857 | 70 3858 | 1 3859 | 10 3860 | 64.662635 3861 | 20 3862 | 61.740990 3863 | 30 3864 | 0.0 3865 | 0 3866 | ENDSEC 3867 | 0 3868 | SECTION 3869 | 2 3870 | OBJECTS 3871 | 0 3872 | DICTIONARY 3873 | 5 3874 | C 3875 | 330 3876 | 0 3877 | 100 3878 | AcDbDictionary 3879 | 3 3880 | ACAD_GROUP 3881 | 350 3882 | D 3883 | 3 3884 | ACAD_MLINESTYLE 3885 | 350 3886 | 17 3887 | 0 3888 | DICTIONARY 3889 | 5 3890 | D 3891 | 330 3892 | C 3893 | 100 3894 | AcDbDictionary 3895 | 0 3896 | DICTIONARY 3897 | 5 3898 | 1A 3899 | 330 3900 | C 3901 | 100 3902 | AcDbDictionary 3903 | 0 3904 | DICTIONARY 3905 | 5 3906 | 17 3907 | 330 3908 | C 3909 | 100 3910 | AcDbDictionary 3911 | 3 3912 | STANDARD 3913 | 350 3914 | 18 3915 | 0 3916 | DICTIONARY 3917 | 5 3918 | 19 3919 | 330 3920 | C 3921 | 100 3922 | AcDbDictionary 3923 | 0 3924 | ENDSEC 3925 | 0 3926 | EOF 3927 | -------------------------------------------------------------------------------- /Faceplate/Touchphat Plate Cut.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 19 | 21 | 42 | 44 | 45 | 47 | image/svg+xml 48 | 50 | 51 | 52 | 53 | 54 | 59 | 62 | 82 | 83 | 88 | 93 | 97 | 101 | 105 | 109 | 110 | 111 | -------------------------------------------------------------------------------- /Faceplate/Touchphat Plate.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 19 | 21 | 42 | 44 | 45 | 47 | image/svg+xml 48 | 50 | 51 | 52 | 53 | 54 | 59 | 62 | 82 | 83 | 88 | 97 | 100 | 106 | 112 | 113 | 118 | 123 | 124 | 125 | -------------------------------------------------------------------------------- /Faceplate/faceplate.rld: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeekyTim/PiHue/138e6b07ee0e99f3554fcc7ed1ccdf614d627b16/Faceplate/faceplate.rld -------------------------------------------------------------------------------- /Faceplate/runtp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GeekyTim/PiHue/138e6b07ee0e99f3554fcc7ed1ccdf614d627b16/Faceplate/runtp.png -------------------------------------------------------------------------------- /PiHue/PiHue.service: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=Start the TouchpHAT Hue controller 3 | After=multi-user.target 4 | 5 | [Service] 6 | Type=idle 7 | User=pi 8 | ExecStart=/usr/bin/python3 /home/pi/PiHue/code/PiHueRoom.py 9 | Restart=always 10 | RestartSec=10 11 | 12 | [Install] 13 | WantedBy=multi-user.target 14 | -------------------------------------------------------------------------------- /PiHue/code/PiHueLightList.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | 3 | ''' 4 | File name: PiHueLightList.py 5 | Author: Tim Richardson 6 | Date created: 04/07/2017 7 | Date last modified: 10/07/2017 8 | Python Version: 3.4 9 | 10 | Description: 11 | Control Philips Hue lights using a Pimoroni TouchpHAT - individual light version 12 | 13 | Requirements: 14 | * Raspberry Pi (http://raspberrypi.org/) 15 | * Philips Hue (http://www2.meethue.com) 16 | * Pimoroni TouchpHAT (https://shop.pimoroni.com/products/touch-phat) 17 | 18 | The Raspberry Pi must be on the same network as the Hue bridge 19 | You must set the bridge to be the IP address of your bridge 20 | and edit the list of lights in your network in 'lights[]' 21 | 22 | You can edit/expand the colour 'xy' values and the alerts 23 | ''' 24 | 25 | import time 26 | 27 | import touchphat 28 | # Import libraries 29 | # Install phue and touchphat with pip3 30 | # pip3 install phue 31 | # pip3 install touchphat 32 | from phue import Bridge 33 | 34 | # ============================================================================================== 35 | # Setup 36 | # ============================================================================================== 37 | touchphat.all_off() 38 | 39 | # !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 40 | # Stuff you need to change! 41 | # !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 42 | # The IP address of the Hue bridge and a list of lights you want to use 43 | bridgeip = 'StarFleet-Hue.localdomain' #'192.168.13.178' # <<<<<<<<<<< 44 | lights = ['Desk', 'Ikea'] # <<<<<<<<<<< 45 | 46 | # ----------------------------------------------------------------------------------------------- 47 | # Do some internal setup 48 | # ----------------------------------------------------------------------------------------------- 49 | # Connect to the bridge 50 | b = Bridge(bridgeip) 51 | 52 | # IMPORTANT: If running for the first time: 53 | # Uncomment the b.connect() line 54 | # Ppress button on bridge 55 | # Run the code 56 | # This will save your connection details in /home/pi/.python_hue 57 | # Delete that file if you change bridges 58 | # b.connect() # <<<<<<<<<< 59 | 60 | # An array of the light name and the light type. 61 | # Expand if you have something different - please let me know if you do! 62 | lighttype = [] 63 | lighttypecolour = 'Extended color light' 64 | lighttypedimmable = 'Dimmable light' 65 | 66 | # Get the type of lights that are connected 67 | for light in lights: 68 | lighttype.append([light, b.get_light(light, 'type')]) 69 | 70 | # Hue 'xy' colours - expand at will 71 | red = (0.675, 0.322) 72 | green = (0.4091, 0.518) 73 | blue = (0.167, 0.04) 74 | yellow = (0.4325035269415173, 0.5007488105282536) 75 | blueviolet = (0.2451169740627056, 0.09787810393609737) 76 | orange = (0.6007303214398861, 0.3767456073628519) 77 | white = (0.32272672086556803, 0.3290229095590793) 78 | 79 | # Alert Patterns 80 | # Used to change the status of lights 81 | # First two numbers are the number of repeat cycles, and the delay between changes 82 | # Followed by dictionaries of the change of light status. 83 | # Use any valid HUE setting - e.g. on, bri, xy, ct, sat, hue, transformationtime 84 | alert_red = [6, 0.5, 85 | {lighttypecolour : {'on': True, 'bri': 255, 'xy': red, 'transitiontime': 0}, 86 | lighttypedimmable: {'on': True, 'bri': 255, 'transitiontime': 0}}, 87 | {lighttypecolour : {'on': False, 'bri': 255, 'xy': red, 'transitiontime': 0}, 88 | lighttypedimmable: {'on': False, 'bri': 255, 'transitiontime': 0}}] 89 | 90 | alert_amber = [6, 0.5, 91 | {lighttypecolour : {'on': True, 'bri': 255, 'xy': orange, 'transitiontime': 0}, 92 | lighttypedimmable: {'on': True, 'bri': 255, 'transitiontime': 0}}, 93 | {lighttypecolour : {'on': False, 'bri': 255, 'xy': orange, 'transitiontime': 0}, 94 | lighttypedimmable: {'on': False, 'bri': 255, 'transitiontime': 0}}] 95 | 96 | alert_blue = [6, 0.5, 97 | {lighttypecolour : {'on': True, 'bri': 255, 'xy': blue, 'transitiontime': 0}, 98 | lighttypedimmable: {'on': True, 'bri': 255, 'transitiontime': 0}}, 99 | {lighttypecolour : {'on': False, 'bri': 255, 'xy': blue, 'transitiontime': 0}, 100 | lighttypedimmable: {'on': False, 'bri': 255, 'transitiontime': 0}}] 101 | 102 | alert_green = [6, 0.5, 103 | {lighttypecolour : {'on': True, 'bri': 255, 'xy': green, 'transitiontime': 0}, 104 | lighttypedimmable: {'on': True, 'bri': 255, 'transitiontime': 0}}, 105 | {lighttypecolour : {'on': False, 'bri': 255, 'xy': green, 'transitiontime': 0}, 106 | lighttypedimmable: {'on': False, 'bri': 10, 'transitiontime': 0}}] 107 | 108 | allwhite = {lighttypecolour : {'on': True, 'bri': 255, 'xy': white, 'transitiontime': 4}, 109 | lighttypedimmable: {'on': True, 'bri': 255, 'transitiontime': 4}} 110 | 111 | # If an alert is ongoing, this will be True 112 | alert_in_progress = False 113 | 114 | # Wait time between sending messages to the bridge - to stop congestion 115 | waittime_default = 0.41 116 | 117 | 118 | # = End of Setup ============================================================================ 119 | 120 | # ------------------------------------------------------------------------------------------- 121 | # Functions 122 | # ------------------------------------------------------------------------------------------- 123 | 124 | """ 125 | Get the status of every light in the list of lights 126 | Extend this if there are more light types in your network 127 | Return Value: Dictionary of the status of all lights in the list 128 | """ 129 | def getlightstatus(): 130 | light_status = {} 131 | for light in lights: 132 | light_type = b.get_light(light, 'type') 133 | if light_type == lighttypecolour: 134 | light_status.update({light: {'on' : b.get_light(light, 'on'), 135 | 'bri': b.get_light(light, 'bri'), 136 | 'xy' : b.get_light(light, 'xy')}}) 137 | elif light_type == lighttypedimmable: 138 | light_status.update({light: {'on' : b.get_light(light, 'on'), 139 | 'bri': b.get_light(light, 'bri')}}) 140 | 141 | return light_status 142 | 143 | 144 | """ 145 | Return the status of the lights to what they were before the alert 146 | Input: Dictionary of the status of all lights in the list (obtained from getlightstatus()) 147 | """ 148 | def putlightstatus(light_status): 149 | global lights 150 | 151 | for light in lights: 152 | b.set_light(light, light_status[light]) 153 | time.sleep(waittime_default) 154 | 155 | 156 | # Runs through the alert dictionary defined in alert_pattern 157 | # Input: alert_pattern containes the pre-defined alert pattern 158 | def huealert(alert_pattern): 159 | global alert_in_progress, lighttype 160 | 161 | # Only run if we're not already in an alert 162 | if not alert_in_progress: 163 | alert_in_progress = True 164 | # Get the current status of the lamps 165 | preAlertStatus = getlightstatus() 166 | 167 | # Using the pre-defined alert patterns, change the lamp status 168 | for rep in range(alert_pattern[0]): 169 | for runalert in range(2, len(alert_pattern)): 170 | for light in lighttype: 171 | b.set_light(light[0], alert_pattern[runalert][light[1]]) 172 | time.sleep(alert_pattern[1]) 173 | 174 | # Return the lamps to the previous status 175 | putlightstatus(preAlertStatus) 176 | alert_in_progress = False 177 | 178 | 179 | # Identifies if any of the lamps in the list are on 180 | # Return Value: True if any lamps are on, otherwise False 181 | def islampon(): 182 | global alert_in_progress 183 | 184 | result = False 185 | 186 | if not alert_in_progress: 187 | islighton = getlightstatus() 188 | for light in lights: 189 | if islighton[light]['on']: 190 | result = True 191 | 192 | return result 193 | 194 | 195 | # When the A button is pressed, run redalert 196 | @touchphat.on_touch("A") 197 | def toucha(): 198 | huealert(alert_red) 199 | touchphat.led_off("A") 200 | 201 | 202 | # When the B button is pressed, run alert_amber 203 | @touchphat.on_touch("B") 204 | def touchb(): 205 | huealert(alert_amber) 206 | touchphat.led_off("B") 207 | 208 | 209 | # When the C button is pressed, run alert_green 210 | @touchphat.on_touch("C") 211 | def touchc(): 212 | huealert(alert_green) 213 | touchphat.led_off("C") 214 | 215 | 216 | # When the D button is pressed, run alert_blue 217 | @touchphat.on_touch("D") 218 | def touchd(): 219 | huealert(alert_blue) 220 | touchphat.led_off("D") 221 | 222 | 223 | # When 'enter' is pressed, all lights are turned on to 'bright white' 224 | # (i.e. what is defined in the dictionary 'allwhite'. Change at will. 225 | @touchphat.on_touch("Enter") 226 | def touchenter(): 227 | global lighttype 228 | 229 | for light in lighttype: 230 | b.set_light(light[0], allwhite[light[1]]) 231 | time.sleep(waittime_default) 232 | touchphat.led_off("Enter") 233 | touchphat.led_on("Back") 234 | 235 | 236 | # When the Back button is pressed, toggle the lamp on/off status 237 | @touchphat.on_touch("Back") 238 | def touchback(): 239 | global alert_in_progress 240 | 241 | if not alert_in_progress: 242 | lampon = islampon() 243 | alert_in_progress = True 244 | if lampon: 245 | for light in lights: 246 | b.set_light(light, 'on', False) 247 | touchphat.led_off("Back") 248 | else: 249 | for light in lights: 250 | b.set_light(light, 'on', True) 251 | touchphat.led_on("Back") 252 | time.sleep(1) 253 | alert_in_progress = False 254 | 255 | 256 | # ================================================================ 257 | # Main loop - keep going forever 258 | # ================================================================ 259 | while True: 260 | if alert_in_progress: 261 | time.sleep(1) 262 | else: 263 | if islampon(): 264 | touchphat.led_on("Back") 265 | else: 266 | touchphat.led_off("Back") 267 | time.sleep(1) 268 | -------------------------------------------------------------------------------- /PiHue/code/PiHueRoom.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | 3 | """ 4 | File name: PiHueRoom.py 5 | Author: Tim Richardson 6 | Date created: 04/07/2017 7 | Date last modified: 14/08/2021 8 | Python Version: 3.4 9 | 10 | Description: 11 | Control Philips Hue lights using a Pimoroni TouchpHAT - Room version 12 | 13 | Requirements: 14 | * Raspberry Pi (http://raspberrypi.org/) 15 | * Philips Hue (http://www2.meethue.com) 16 | * Pimoroni Touch pHAT (https://shop.pimoroni.com/products/touch-phat) 17 | 18 | The Raspberry Pi must be on the same network as the Hue bridge 19 | You must set the bridge to be the IP address of your bridge 20 | and edit the room constant 'roomname' 21 | 22 | You can edit/expand the colour 'xy' values and the alerts 23 | 24 | Import libraries 25 | Install phue and touchphat with pip3: 26 | sudo apt install python3-cap1xxx python3-pip python3-touchphat 27 | sudo pip3 install phue 28 | """ 29 | 30 | from signal import pause 31 | 32 | import touchphat 33 | import configparser 34 | import huecontrol 35 | import colourconfig 36 | 37 | # ============================================================================================== 38 | # Setup 39 | # ============================================================================================== 40 | touchphat.all_off() 41 | 42 | 43 | # ------------------------------------------------------------------------------------------- 44 | # Functions 45 | # ------------------------------------------------------------------------------------------- 46 | # When the A button is pressed, run alert_red 47 | @touchphat.on_touch("A") 48 | def toucha(): 49 | huelights.alert(colourconfig.alert_red) 50 | touchphat.led_off("A") 51 | 52 | 53 | # When the B button is pressed, run alert_amber 54 | @touchphat.on_touch("B") 55 | def touchb(): 56 | huelights.alert(colourconfig.alert_amber) 57 | touchphat.led_off("B") 58 | 59 | 60 | # When the C button is pressed, run alert_green 61 | @touchphat.on_touch("C") 62 | def touchc(): 63 | huelights.alert(colourconfig.alert_green) 64 | touchphat.led_off("C") 65 | 66 | 67 | # When the D button is pressed, run alert_blue 68 | @touchphat.on_touch("D") 69 | def touchd(): 70 | huelights.alert(colourconfig.alert_blue) 71 | touchphat.led_off("D") 72 | 73 | 74 | # When 'enter' is pressed, the room is turned on to 'bright white' 75 | # (i.e. what is defined in the dictionary 'allwhite'. Change at will. 76 | @touchphat.on_touch("Enter") 77 | def touchenter(): 78 | huelights.setcolour(colourconfig.allwhite) 79 | touchphat.led_on("Enter") 80 | touchphat.led_off("Back") 81 | 82 | 83 | # When the Back button is pressed, toggle the lamp on/off status 84 | @touchphat.on_touch("Back") 85 | def touchback(): 86 | huelights.turnoff() 87 | touchphat.led_off("Back") 88 | touchphat.led_off("Enter") 89 | 90 | 91 | # ================================================================ 92 | # Main loop - keep going forever 93 | # ================================================================ 94 | def main(): 95 | pause() 96 | 97 | 98 | if __name__ == "__main__": 99 | hueconfig = configparser.ConfigParser() 100 | hueconfig.read("/home/pi/PiHue/code/hueconfig.cfg") 101 | print(hueconfig.sections()) 102 | 103 | huelights = huecontrol.HueControl(hueconfig.get('Hue','bridge'), hueconfig.get('Hue','roomname'), 104 | int(hueconfig.get('Hue','waittime'))) 105 | main() 106 | -------------------------------------------------------------------------------- /PiHue/code/colourconfig.py: -------------------------------------------------------------------------------- 1 | # !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 2 | # Stuff you need to change! 3 | # !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 4 | 5 | """ 6 | Hue 'xy' colours - expand at will 7 | """ 8 | red = (0.675, 0.322) 9 | green = (0.4091, 0.518) 10 | blue = (0.167, 0.04) 11 | yellow = (0.4325035269415173, 0.5007488105282536) 12 | blueviolet = (0.2451169740627056, 0.09787810393609737) 13 | orange = (0.6007303214398861, 0.3767456073628519) 14 | white = (0.32272672086556803, 0.3290229095590793) 15 | 16 | """ 17 | Alert Patterns 18 | Used to change the status of lights 19 | The first number is the number of repeat cycles. 20 | The second is the delay between changes. 21 | The following dictionaries are the change of light status. 22 | Use any valid HUE setting - e.g. on, bri, xy, ct, sat, hue, transformationtime 23 | But remember that dimmable lamps only dim ('bri') and don't change colour ('no 'xy') 24 | """ 25 | alert_red = [6, 1.0, 26 | {'on': True, 'bri': 255, 'xy': red}, 27 | {'on': False}] 28 | 29 | alert_amber = [6, 1.0, 30 | {'on': True, 'bri': 255, 'xy': orange}, 31 | {'on': False}] 32 | 33 | alert_green = [6, 1.0, 34 | {'on': True, 'bri': 255, 'xy': green}, 35 | {'on': False}] 36 | 37 | alert_blue = [6, 1.0, 38 | {'on': True, 'bri': 255, 'xy': blue}, 39 | {'on': False}] 40 | 41 | # For turning the lights all on to bright white 42 | allwhite = {'on': True, 'bri': 255, 'xy': white} 43 | -------------------------------------------------------------------------------- /PiHue/code/hueconfig.cfg: -------------------------------------------------------------------------------- 1 | [Hue] 2 | # The IP address of the Hue bridge and a list of lights you want to use 3 | bridge=StarFleet-Hue 4 | # The 'group' of lights you want to change - i.e. the Room Name in the Hue app 5 | roomname=Hut 8 6 | # Wait time between sending messages to the bridge - to stop congestion 7 | waittime=1 8 | -------------------------------------------------------------------------------- /PiHue/code/huecontrol.py: -------------------------------------------------------------------------------- 1 | import time 2 | 3 | from phue import Bridge 4 | 5 | 6 | class HueControl: 7 | """ 8 | Controls the Hue Lights 9 | """ 10 | 11 | def __init__(self, bridge, roomname, waittime): 12 | """ 13 | IMPORTANT: If running for the first time: 14 | Uncomment the b.connect() line 15 | Press button on bridge 16 | Run the code 17 | This will save your connection details in /home/pi/.python_hue 18 | Delete that file if you change bridges 19 | 20 | :param bridge: 21 | :param roomname: 22 | :return: 23 | """ 24 | 25 | try: 26 | # Connect to the bridge 27 | self.__bridge = Bridge(bridge) 28 | # self.__bridge.connect() # Uncomment to connect to the bridge <<<<<<<<<< 29 | except: 30 | print("Unable to connect to the bridge") 31 | exit() 32 | 33 | # Find the room number from the room name 34 | roomnumber = 0 35 | allrooms = self.__bridge.get_group() 36 | 37 | for room in allrooms.keys(): 38 | if allrooms[room]['name'] == roomname: 39 | roomnumber = int(room) 40 | break 41 | 42 | if roomnumber == 0: 43 | print('The room name you have supplied in roomname is not recognised. Please try again. Exiting.') 44 | exit() 45 | 46 | self.__waittime = waittime 47 | self.__roomnumber = roomnumber 48 | self.__alertinprogress = False 49 | self.__roomstatus = self.__bridge.get_group(self.__roomnumber) 50 | 51 | def __getroomstatus(self): 52 | """ 53 | Get the status of a room BEFORE the alert is set, so it can be returned to that state 54 | """ 55 | self.__roomstatus = self.__bridge.get_group(self.__roomnumber) 56 | 57 | def __resetroomstatus(self): 58 | """ 59 | Return the status of the room to what it was before the alert 60 | """ 61 | self.__bridge.set_group(self.__roomnumber, 62 | {'xy': self.__roomstatus['action']['xy'], 'bri': self.__roomstatus['action']['bri'], 63 | 'on': self.__roomstatus['action']['on']}, transitiontime=0) 64 | time.sleep(self.__waittime) 65 | 66 | def alert(self, alertpattern): 67 | """ 68 | Runs through the alert dictionary defined in alert_pattern 69 | 70 | :param alertpattern: containes the pre-defined alert pattern 71 | """ 72 | self.__getroomstatus() 73 | 74 | # Using the pre-defined alert patterns, change the lamp status 75 | for rep in range(alertpattern[0]): 76 | for runalert in range(2, len(alertpattern)): 77 | self.__bridge.set_group(self.__roomnumber, alertpattern[runalert], transitiontime=0) 78 | time.sleep(alertpattern[1]) 79 | # Return the lamps to the previous status 80 | self.__resetroomstatus() 81 | 82 | def setcolour(self, colour): 83 | """ 84 | 85 | :param colour: The colour to set the lights to 86 | :return: 87 | """ 88 | self.__bridge.set_group(self.__roomnumber, colour, transitiontime=0) 89 | time.sleep(self.__waittime) 90 | 91 | def turnoff(self): 92 | """ 93 | Turns all the lights off 94 | """ 95 | self.__bridge.set_group(self.__roomnumber, 'on', False) 96 | time.sleep(self.__waittime) 97 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # PiHue 2 | Controlling Philips Hue with a Pimoroni Touch pHAT 3 | 4 | ## Introduction 5 | The purpose of this code is to control Philips Hue lights using a Raspberry Pi and Pimoroni Touch pHAT. Each button on the Touch pHAT can have a different function. In this case I have decided on the following: 6 | * The 'Return' button will toggle the lights on and off. The LED indicator will show you whether any lights in the room/list are on. 7 | * The 'Enter' button will turn all the lights in the room or list to bright. 8 | * Button 'A' will flash the lights red 9 | * Button 'B' will flash the lights amber 10 | * Button 'C' will flash the lights green 11 | * Button 'D' will flash the lights blue 12 | 13 | The intended use is for the Touch pHAT to be placed in one room and the lights in another (or in my case, Hut 8) alert me to a situation (e.g. dinner is ready, she is home, phone call etc.). I can also turn off the lights remotely without using the Hue app or Alexa. 14 | 15 | ## Hardware Requirements 16 | * [Raspberry Pi](http://raspberrypi.org/) 17 | * SD card with RaspberryOS installed (preferably RaspberryOS Lite) 18 | * Connected to the same network as the Philips Hue 19 | * [Philips Hue](http://www2.meethue.com) 20 | * You need to know the IP address of your Hue bridge. 21 | * [Pimoroni Touch pHAT](https://shop.pimoroni.com/products/touch-phat) 22 | 23 | ## Prerequisites 24 | Some prerequisites need to be installed for this code: 25 | * Python 3, PIP and GIT 26 | ```text 27 | sudo apt update && sudo apt upgrade 28 | sudo apt install python3 python3-pip git 29 | * The Pimoroni Touch pHAT library 30 | ```text 31 | apt install python3-touchphat 32 | * The 'phue' Python Hue library from [StudioImagineaire](http://studioimaginaire.com/en/projects/phue/), and available on [GitHub](https://github.com/studioimaginaire/phue) 33 | ```text 34 | sudo pip3 install phue 35 | ## Cloning from GitHub 36 | The best way to get this code is to clone it from GitHub with: 37 | 38 | git clone https://github.com/GeekyTim/PiHue 39 | 40 | The PiHue code will be in the folder ``PiHue`` 41 | 42 | cd PiHue 43 | 44 | ## Set Up 45 | There are two versions of the code: 46 | * One that controls a room of lights (i.e. a Room): PiHueRoom.py 47 | * Another that controls individual lights: PiHueLightList.py 48 | 49 | Choose which version you prefer. I find that the Room version works best with one room that contains both a dimable light and a colour light. 50 | 51 | Edit the code to make the following **REQUIRED** changes: 52 | * For PiHueRoom.py: 53 | * Change the IP address of your Philips Hue: ``bridgeip`` 54 | * Change the name of the room you want to control: ``roomname`` 55 | * For PiHueLightList.py: 56 | * Change the IP address of your Philips Hue: ``bridgeip`` 57 | * Change the names of the lights you want to control in the Python list: ``lights`` 58 | 59 | Optionally you can change the list of 'xy' colours by adding/altering/replacing to those already listed under ```# Hue 'xy' colours - expand at will``` 60 | You can change the 'alert' patterns in the section following ``# Alert Patterns``. These are Python lists: 61 | * The first two numbers are the number of repeat cycles, and the delay between light changes. Recommended minimum delay between changes is 0.4s. 62 | * The remaining values are Python dictionaries of the light status changes. 63 | * Use any valid Hue status, e.g. 'on', 'bri', 'xy', 'ct', 'sat', 'hue', 'transformationtime'. 64 | * Remember that Dimable Lights do not accept any of the colour changes (i.e. 'xy', 'ct', 'sat', 'hue'), so you will need to change their brightness. 65 | * You can have as many changes as you need. 66 | * For Rooms, if you have dimmable lights as well as colour lights, you should alter the brightness as well as the colour of the rooms' lights. 67 | * For Light Lists the status changes are themselves Python dictionaries that contain the changes for each light type (e.g. 'Extended color light' 68 | and 'Dimmable light'). If you have different light types, you can add them to the dictionary. 69 | * There is one special dictionary that is used by the 'enter' key to set all lights to on and maximum white: ``allwhite``. You can redefine this to be any colour and brightness that you prefer. 70 | 71 | ## Running the Code for the First Time 72 | The first time you run the code, you **MUST** first uncomment the line ``# b.connect()`` and press your Bridge connect button just before running the code with either: 73 | 74 | python3 PiHueRoom.py 75 | 76 | or 77 | 78 | python3 PiHueLightList.py 79 | 80 | Your Pi should connect to the Bridge and save the Bridge details and user in the file ``/home/pi/.python_hue`` 81 | 82 | If you ever need to change your Bridge details, just delete this file. 83 | 84 | You can now recomment the ``self.__bridge.connect()`` line. 85 | 86 | ## Running on Boot 87 | There are a few ways to run Python code on booting your Raspberry Pi. My preferred method is to use Systemd. 88 | 89 | ### Create A 'Unit File' 90 | Create a configuration file (aka a unit file) that tells systemd what we want it to do and when: 91 | 92 | sudo nano /lib/systemd/system/PiHue.service 93 | 94 | Add in the following text (replacing PiHueRoom.py with PiHueLightList.py as required): 95 | 96 | [Unit] 97 | Description=PiHue Service 98 | After=multi-user.target 99 | 100 | [Service] 101 | Type=idle 102 | User=pi 103 | Restart=always 104 | RestartSec=5 105 | ExecStart=/usr/bin/python3 /home/pi/PiHue/PiHueRoom.py 106 | 107 | [Install] 108 | WantedBy=multi-user.target 109 | 110 | Save and exit the nano editor using [CTRL-X], [Y] then [ENTER]. 111 | 112 | This defines a new service called “PiHue Service”. 113 | 114 | The permission on the unit file needs to be set to 644 : 115 | 116 | sudo chmod 644 /lib/systemd/system/PiHue.service 117 | 118 | ### Configure systemd 119 | 120 | Instruct systemd to start the service during the boot sequence: 121 | 122 | sudo systemctl daemon-reload 123 | sudo systemctl enable PiHue.service 124 | 125 | Reboot the Pi and the PiHue service should run: 126 | 127 | sudo reboot 128 | 129 | ### Check the Status of the PiHue service 130 | 131 | You can check the status of your service using: 132 | 133 | sudo systemctl status PiHue.service 134 | 135 | This should return something looking like: 136 | 137 | PiHue.service - Start the TouchpHAT Hue controller 138 | Loaded: loaded (/lib/systemd/system/PiHue.service; enabled) 139 | Active: active (running) since Mon 2017-07-10 23:26:52 UTC; 15min ago 140 | Main PID: 746 (python3) 141 | CGroup: /system.slice/PiHue.service 142 | └─746 /usr/bin/python3 /home/pi/PiHue/PiHueRoom.py 143 | 144 | Jul 10 23:26:52 PiHue systemd[1]: Starting Start the TouchpHAT Hue controller... 145 | Jul 10 23:26:52 PiHue systemd[1]: Started Start the TouchpHAT Hue controller. 146 | 147 | ## Rebooting your Raspberry Pi on Network Loss 148 | 149 | You may find that your Raspberry Pi occasionally disconnects from your network, especially if you are using Wi-Fi. Once disconnected, unless you do restart the network interface or reboot the Pi, it will remain disconnected. 150 | 151 | If this is happening then you may want to use this little service to reboot your Pi, but be careful, if you move the IP address you set becomes unavailable (e.g. if you use your Pi away from home) then it may keep rebooting itself ad infinitum! 152 | 153 | Follow the instructions by Thijs Bernolet on his [blog](http://weworkweplay.com/play/rebooting-the-raspberry-pi-when-it-loses-wireless-connection-wifi/) to enable reboot on network loss. 154 | 155 | 156 | ## Suggestions 157 | This code is only an example of what I want to use the TouchpHAT to do. There is plenty more - like having each button turn on a different light in the house, or connecting a motion or temperature sensor to change light colour - feel free to take this code and modify at will, but PLEASE attribute both the 'phue' [library developer](https://github.com/studioimaginaire/phue) and myself as is customary. 158 | 159 | Please feel free to tweet me [@Geeky_Tim](https://twitter.com/Geeky_Tim) 160 | -------------------------------------------------------------------------------- /code/.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto -------------------------------------------------------------------------------- /code/.gitignore: -------------------------------------------------------------------------------- 1 | # Byte-compiled / optimized / DLL files 2 | __pycache__/ 3 | *.py[cod] 4 | *$py.class 5 | 6 | # C extensions 7 | *.so 8 | 9 | # Distribution / packaging 10 | .Python 11 | env/ 12 | build/ 13 | develop-eggs/ 14 | dist/ 15 | downloads/ 16 | eggs/ 17 | .eggs/ 18 | lib/ 19 | lib64/ 20 | parts/ 21 | sdist/ 22 | var/ 23 | wheels/ 24 | *.egg-info/ 25 | .installed.cfg 26 | *.egg 27 | 28 | # PyInstaller 29 | # Usually these files are written by a python script from a template 30 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 31 | *.manifest 32 | *.spec 33 | 34 | # Installer logs 35 | pip-log.txt 36 | pip-delete-this-directory.txt 37 | 38 | # Unit test / coverage reports 39 | htmlcov/ 40 | .tox/ 41 | .coverage 42 | .coverage.* 43 | .cache 44 | nosetests.xml 45 | coverage.xml 46 | *,cover 47 | .hypothesis/ 48 | 49 | # Translations 50 | *.mo 51 | *.pot 52 | 53 | # Django stuff: 54 | *.log 55 | local_settings.py 56 | 57 | # Flask stuff: 58 | instance/ 59 | .webassets-cache 60 | 61 | # Scrapy stuff: 62 | .scrapy 63 | 64 | # Sphinx documentation 65 | docs/_build/ 66 | 67 | # PyBuilder 68 | target/ 69 | 70 | # Jupyter Notebook 71 | .ipynb_checkpoints 72 | 73 | # pyenv 74 | .python-version 75 | 76 | # celery beat schedule file 77 | celerybeat-schedule 78 | 79 | # dotenv 80 | .env 81 | 82 | # virtualenv 83 | .venv/ 84 | venv/ 85 | ENV/ 86 | 87 | # Spyder project settings 88 | .spyderproject 89 | 90 | # Rope project settings 91 | .ropeproject 92 | .idea/Hut8Hue.iml 93 | .idea/deployment.xml 94 | .idea/inspectionProfiles/profiles_settings.xml 95 | .idea/misc.xml 96 | .idea/modules.xml 97 | .idea/remote-mappings.xml 98 | .idea/vcs.xml 99 | .idea/webServers.xml 100 | .idea/workspace.xml 101 | grouptest.py 102 | .idea/preferred-vcs.xml 103 | --------------------------------------------------------------------------------