├── README.md ├── heaters └── examples │ ├── bash │ └── query_ambient_temperature.sh │ └── python │ ├── authentication_and_HTTP.py │ ├── basic_control.py │ ├── temperature_control.py │ └── timers.py └── postman_collection_heaters_gen_3.json /README.md: -------------------------------------------------------------------------------- 1 | # Millheat heater gen. 3 - local WiFi Control API - version 0x220727 (27.07.2022) 2 | 3 | ## Overview 4 | 5 | Following devices are supported: 6 | 7 | - Panel heaters - Generation 3. 8 | - Convection heaters - Generation 3. 9 | - Oil heaters - Generation 3. 10 | - Wi-Fi Socket - Generation 3. 11 | 12 | Generation 3 heaters expose HTTP server, with a defined REST API. Local HTTP server works both when the device is connected to an existing WiFi network (to a router) or when the device is configured as an Access Point. 13 | In the first scenario, the device IP address can be found in the router clients list. 14 | In most cases, it is something like 192.168.1.105 or 10.0.0.95, depending on the local network configuration. 15 | Once you have an IP address, you can just type it in a web browser (assuming your device is connected to the same WiFi network) to see the main page. It contains a summary of the heater status and reference to this document. 16 | In the Access Point mode the heater has IP address `192.168.4.1`. 17 | 18 | 19 | ## HTTP Requests 20 | 21 | All API requests are made by sending a HTTP request using one of the following methods, depending on the action being taken: 22 | 23 | - POST create a resource, 24 | - GET get a resource or list of resources. 25 | 26 | Request data is passed as a JSON file content in the request body. Response data is also returned as a JSON file, with the scheme described below. 27 | 28 | ## HTTP Responses 29 | 30 | Each response will include a`result` (`result` will be an object for single-record queries and an array for list queries) and `status` message. The `status` message contain the information of the result of the processing request. The list of status codes can be found in [HTTP Response Codes](#http-esponse-codes). The `result` contains the result of a successful request. For example, a request to the [GET status](#get-status) resource might return this: 31 | 32 | ```json 33 | { 34 | "name": "panel heater gen. 3", 35 | "custom_name": "", 36 | "version": "0x210927", 37 | "operation_key": "", 38 | "mac_address": "XX:XX:XX:XX:XX:XX", 39 | "status": "ok" 40 | } 41 | ``` 42 | 43 | 44 | ## HTTP Response Status 45 | 46 | Each response will be returned the field status with one of the following description: 47 | 48 | - ok - the request was successful, 49 | - Failed to parse message body - the request body is incorrect or the parameters are invalid, 50 | - Failed to execute the request - there was a problem with the processing request, 51 | - Length of request body too long - the length of the request body is to long, 52 | - Failed to create response body - there was a problem with the processing respone. 53 | 54 | ## Resources 55 | 56 | We provide a [Postman](https://www.getpostman.com/) collection with a set of requests that introduce the basic concepts of the API. The Postman collection and more information are available [here](postman_collection_heaters_gen_3.json). In the collection {{heater_addresss}} is the variable which determines the IP address of the device. 57 | 58 | ## Authentication 59 | After setting API key with [POST/set-api-key](#postset-api-key) every request on every endpoint would need to contain this key as header. This operation (settign API key) triggers product to restart to change HTTP server to HTTPS server. That server uses self-signed certificate which can generate some warning massages but will provide better security. 60 | Header's key must be "Authentication" and it's value should be API key. 61 | 62 | ### Basic communication 63 | 64 | - [GET/status](#getstatus) 65 | - [POST/soft-reset](#postsoft-reset) 66 | - [POST/hard-reset](#posthard-reset) 67 | - [POST/reboot](#postreboot) 68 | - [GET/temperature-calibration-offset](#gettemperature-calibration-offset) 69 | - [POST/temperature-calibration-offset](#posttemperature-calibration-offset) 70 | - [GET/control-status](#getcontrol-status) 71 | - [GET/operation-mode](#getoperation-mode) 72 | - [POST/operation-mode](#postoperation-mode) 73 | - [GET/commercial-lock](#getcommercial-lock) 74 | - [POST/commercial-lock](#postcommercial-lock) 75 | - [GET/child-lock](#getchild-lock) 76 | - [POST/child-lock](#postchild-lock) 77 | - [GET/open-window](#getopen-window) 78 | - [POST/open-window](#postopen-window) 79 | - [GET/weekly-program](#getweekly-program) 80 | - [POST/weekly-program](#postweekly-program) 81 | - [GET/non-repeatable-timers](#getnon-repeatable-timers) 82 | - [POST/non-repeatable-timers](#postnon-repeatable-timers) 83 | - [GET/display-unit](#getdisplay-unit) 84 | - [POST/display-unit](#getdisplay-unit) 85 | - [GET/set-temperature](#getset-temperature) 86 | - [POST/set-temperature](#postset-temperature) 87 | - [GET/oil-heater-power](#getoil-heater-power) 88 | - [POST/oil-heater-power](#postoil-heater-power) 89 | - [GET/predictive-heating-type](#getpredictive-heating-type) 90 | - [POST/predictive-heating-type](#postpredictive-heating-type) 91 | - [POST/overwrite-weekly-program](#postoverwrite-weekly-program) 92 | - [GET/vacation-mode](#getvacation-mode) 93 | - [POST/vacation-mode](#postvacation-mode) 94 | - [GET/timezone-offset](#gettimezone-offset) 95 | - [POST/timezone-offset](#posttimezone-offset) 96 | - [POST/set-temperature-in-independent-mode-now](#postset-temperature-in-independent-mode-now) 97 | - [GET/additional-socket-mode](#getadditional-socket-mode) 98 | - [POST/additional-socket-mode](#postadditional-socket-mode) 99 | 100 | ### Advanced communication 101 | 102 | - [GET/pid-parameters](#getpid-parameters) 103 | - [POST/pid-parameters](#postpid-parameters) 104 | - [GET/cloud-communication](#getcloud-communication) 105 | - [POST/cloud-communication](#postcloud-communication) 106 | - [POST/ota-update](#postota-update) 107 | - [GET/config-parameter](#getconfig-parameter) 108 | - [POST/config-parameter](#postconfig-parameter) 109 | - [POSTpost/max-heater-power](#postmax-heater-power) 110 | - [POST/ablecloud-message](#postablecloud-message) 111 | - [GET/scan-wifi](#getscan-wifi) 112 | - [POST/device-config](#postdevice-config) 113 | - [GET/hysterersis-parameters](#gethysteresis-parameters) 114 | - [POST/hysterersis-parameters](#posthysteresis-parameters) 115 | - [GET/limited-heating-power](#getlimited-heating-power) 116 | - [POST/limited-heating-power](#postlimited-heating-power) 117 | - [GET/controller-type](#getcontroller-type) 118 | - [POST/controller-type](#postcontroller-type) 119 | - [POST/set-custom-name](#postset-custom-name) 120 | - [POST/increase-set-temperature](#postincrease-set-temperature) 121 | - [POST/decrease-set-temperature](#postdecrease-set-temperature) 122 | - [POST/set-api-key](#postset-api-key) 123 | - [GET/commercial-lock-customization](#getcommercial-lock-customization) 124 | - [POST/commercial-lock-customization](#postcommercial-lock-customization) 125 | 126 | 127 | 128 | ## Examples 129 | 130 | Here, we provide example Python scripts which can control the Millheat heater gen. 3 via the REST API: 131 | 132 | - [examples/python/basic_control.py](heaters/examples/python/basic_control.py) script queries the current control status to obtain current temperature and control signal (how much the heater is heating). Then it changes the set temperature every minute. 133 | - [examples/python/temperature_control.py](heaters/examples/python/temperature_control.py) script queries the status of the status device and set and get the temperature in a given temperature type. Then it changes the set temperature every minute. 134 | - [examples/python/timers.py](heaters/examples/python/timers.py) script sets a few timers scheduled for the next few minutes, and queries the status to confirm the proper behavior. Note that the script doesn't need to keep running to have the timers working - they are stored and executed inside the device. 135 | 136 | We also provide a simple example to control the Millheat heater gen. 3 with a Bash script: 137 | 138 | - In [examples/bash/query_ambient_temperature.sh](heaters/examples/bash/query_ambient_temperature.sh) script the ambient temperature is returned every second. 139 | 140 | ## GET/status 141 | 142 | Return a quick summary of the device information. 143 | 144 | ### Returned parameters 145 | 146 | | Field | Type | Description | 147 | | ------------- | ------ | ------------------------------------------------------------ | 148 | | name | string | the name of the device | 149 | | custom_name | string | the custom name of the device | 150 | | version | string | the API version number | 151 | | operation_key | string | if there is some operation problem (like broken temperature sensor), it may be reported in this field | 152 | | mac_address | string | device's MAC (Media Access Control) address | 153 | 154 | ### Example 155 | 156 | #### Request 157 | 158 | - Postman: 159 | 160 | ```html 161 | GET http://{{heater_address}}/status 162 | ``` 163 | 164 | Request body: empty 165 | 166 | - Curl: 167 | 168 | ```html 169 | curl -X GET -H "Content-Type: application/json" http://{{heater_address}}/status 170 | ``` 171 | 172 | #### Response: 173 | 174 | ```json 175 | { 176 | "name": "panel heater gen. 3", 177 | "custom_name": "", 178 | "version": "0x210927", 179 | "operation_key": "", 180 | "mac_address": "XX:XX:XX:XX:XX:XX", 181 | "status": "ok" 182 | } 183 | ``` 184 | 185 | 186 | 187 | ## POST/soft-reset 188 | 189 | Perform a soft-reset of the device (configuration). 190 | 191 | ### Example 192 | 193 | #### Request 194 | 195 | - Postman: 196 | 197 | ```html 198 | POST http://{{heater_address}}/soft-reset 199 | ``` 200 | 201 | Request body: empty 202 | 203 | 204 | #### Response 205 | 206 | The soft-reset performs before sending response. 207 | 208 | 209 | 210 | ## POST/hard-reset 211 | 212 | Perform a hard-reset of the device. 213 | 214 | ### Example 215 | 216 | #### Request 217 | 218 | - Postman: 219 | 220 | ```html 221 | POST http://{{heater_address}}/hard-reset 222 | ``` 223 | 224 | Request body: empty 225 | 226 | 227 | #### Response 228 | 229 | The hard-reset performs before sending response. 230 | 231 | 232 | 233 | ## POST/reboot 234 | 235 | Perform a reboot of the heater control MCU 236 | 237 | ### Example 238 | 239 | #### Request 240 | 241 | - Postman: 242 | 243 | ```html 244 | POST http://{{heater_address}}/reboot 245 | ``` 246 | 247 | Request body: empty 248 | 249 | 250 | #### Response 251 | 252 | The reboot performs before sending response. 253 | 254 | 255 | 256 | ## GET/temperature-calibration-offset 257 | 258 | Return the current value of temperature sensor calibration offset. 259 | 260 | ### Returned parameters 261 | 262 | | Field | Type | Description | 263 | | ----- | ----- | ----------------------------------------------- | 264 | | value | float | the calibration offset value in Celsius degrees | 265 | 266 | ### Example 267 | 268 | #### Request 269 | 270 | - Postman: 271 | 272 | ```html 273 | GET http://{{heater_address}}/temperature-calibration-offset 274 | ``` 275 | 276 | Request body: empty 277 | 278 | - Curl: 279 | 280 | ```html 281 | curl -X GET -H "Content-Type: application/json" http://{{heater_address}}/temperature-calibration-offset 282 | ``` 283 | 284 | - 285 | 286 | #### Response 287 | 288 | ```json 289 | { 290 | "value": 2.5, 291 | "status": "ok" 292 | } 293 | ``` 294 | 295 | 296 | 297 | ## POST/temperature-calibration-offset 298 | 299 | Set a new value of temperature sensor calibration offset. 300 | 301 | ### Body parameters 302 | 303 | | Field | Type | Description | 304 | | ----- | ----- | ----------------------------------------------- | 305 | | value | float | the calibration offset value in Celsius degrees | 306 | 307 | ### Example 308 | 309 | #### Request 310 | 311 | - Postman: 312 | 313 | ```html 314 | POST http://{{heater_address}}/temperature-calibration-offset 315 | ``` 316 | 317 | Request body: 318 | 319 | ```json 320 | { 321 | "value": 2 322 | } 323 | ``` 324 | 325 | - Curl: 326 | 327 | ```html 328 | curl -X POST -H "Content-Type: application/json" -d '{"value": 2}' http://{{heater_address}}/temperature-calibration-offset 329 | ``` 330 | 331 | 332 | #### Response 333 | 334 | ```json 335 | { 336 | "status": "ok" 337 | } 338 | ``` 339 | 340 | 341 | 342 | ## GET/control-status 343 | 344 | Return detailed information about the current device state and control status. 345 | 346 | ### Returned parameters 347 | 348 | | Field | Type | Description | 349 | | ----------------------- | ------ | ------------------------------------------------------------ | 350 | | ambient_temperature | float | the temperature measured by sensor in Celsius degrees (with calibration offset value included) | 351 | | current_power | float | the current heating power in Watts | 352 | | control_signal | float | the control signal of the PID regulator (0-100%) | 353 | | lock_active | string | the lock status (see [ELockStatus](#elockstatus)) | 354 | | open_window_active_now | string | the open widows status (see [EOpenWindowStatus](#eopenwindowstatus)) | 355 | | raw_ambient_temperature | float | the temperature measured by sensor in Celsius degrees without calibration offset value | 356 | | set_temperature | float | the current set temperature in Celsius degrees | 357 | | switched_on | float | true if the device is switched on - whether it is set to working, with heating | 358 | | connected_to_cloud | bool | the information whether device has connection with the cloud | 359 | | operation_mode | string | the current mode of operation (see [EOprationMode](#eoprationmode)) | 360 | 361 | ### Example 362 | 363 | #### Request 364 | 365 | - Postman: 366 | 367 | ```html 368 | GET http://{{heater_address}}/control-status 369 | ``` 370 | 371 | Request body: empty 372 | 373 | - Curl: 374 | 375 | ```html 376 | curl -X GET -H "Content-Type: application/json" http://{{heater_address}}/control-status 377 | ``` 378 | 379 | 380 | #### Response 381 | 382 | ```json 383 | { 384 | "ambient_temperature": 22, 385 | "current_power": 5, 386 | "control_signal": 100, 387 | "lock_active": "Child lock", 388 | "open_window_active_now": "Enabled not active now", 389 | "raw_ambient_temperature": 21, 390 | "set_temperature": 1, 391 | "switched_on": false, 392 | "connected_to_cloud": true, 393 | "operation_mode": "Control individually", 394 | "status": "ok" 395 | } 396 | ``` 397 | 398 | 399 | 400 | ## GET/operation-mode 401 | 402 | Return the current operation mode. 403 | 404 | ### Returned parameters 405 | 406 | | Field | Type | Description | 407 | | ----- | ------ | ------------------------------------------------------------ | 408 | | mode | string | the current operation mode (see [EOprationMode](#eoprationmode)) | 409 | 410 | ### Example 411 | 412 | #### Request 413 | 414 | - Postman: 415 | 416 | ```html 417 | GET http://{{heater_address}}/operation-mode 418 | ``` 419 | 420 | Request body: empty 421 | 422 | 423 | #### Response 424 | 425 | ```json 426 | { 427 | "mode": "Control individually", 428 | "status": "ok" 429 | } 430 | ``` 431 | 432 | 433 | 434 | ## POST/operation-mode 435 | 436 | Set the operation mode. 437 | 438 | ### Body parameters 439 | 440 | | Field | Type | Description | 441 | | ----- | ------ | ------------------------------------------------------------ | 442 | | mode | string | the operation mode to set (see [EOprationMode](#eoprationmode)) | 443 | 444 | ### Example 445 | 446 | #### Request 447 | 448 | - Postman: 449 | 450 | ```html 451 | POST http://{{heater_address}}/operation-mode 452 | ``` 453 | 454 | Request body: 455 | 456 | ```json 457 | { 458 | "mode": "Control individually" 459 | } 460 | ``` 461 | 462 | 463 | #### Response 464 | 465 | ```json 466 | { 467 | "status": "ok" 468 | } 469 | ``` 470 | 471 | 472 | 473 | ## GET/commercial-lock 474 | 475 | Return the status of the commercial lock. 476 | 477 | ### Returned parameters 478 | 479 | | Field | Type | Description | 480 | | ----- | ---- | --------------------------------- | 481 | | value | bool | the status of the commercial lock | 482 | 483 | ### Example 484 | 485 | #### Request 486 | 487 | - Postman: 488 | 489 | ```html 490 | GET http://{{heater_address}}/commercial-lock 491 | ``` 492 | 493 | Request body: empty 494 | 495 | 496 | #### Response 497 | 498 | ```json 499 | { 500 | "value": true, 501 | "status": "ok" 502 | } 503 | ``` 504 | 505 | 506 | 507 | ## POST/commercial-lock 508 | 509 | Set status of the commercial lock. 510 | 511 | ### Body parameters 512 | 513 | | Field | Type | Description | 514 | | ----- | ---- | ---------------------------------------- | 515 | | value | bool | the status of the commercial lock to set | 516 | 517 | ### Example 518 | 519 | #### Request 520 | 521 | - Postman: 522 | 523 | ```html 524 | GET http://{{heater_address}}/commercial-lock 525 | ``` 526 | 527 | Request body: 528 | 529 | ```json 530 | { 531 | "value": true 532 | } 533 | ``` 534 | 535 | 536 | #### Response 537 | 538 | ```json 539 | { 540 | "status": "ok" 541 | } 542 | ``` 543 | 544 | 545 | 546 | ## GET/child-lock 547 | 548 | Return the status of the child lock. 549 | 550 | ### Returned parameters 551 | 552 | | Field | Type | Description | 553 | | ----- | ---- | ---------------------------- | 554 | | value | bool | the status of the child lock | 555 | 556 | ### Example 557 | 558 | #### Request 559 | 560 | - Postman: 561 | 562 | ```html 563 | GET http://{{heater_address}}/child-lock 564 | ``` 565 | 566 | Request body: empty 567 | 568 | 569 | #### Response 570 | 571 | ```json 572 | { 573 | "value": false, 574 | "status": "ok" 575 | } 576 | ``` 577 | 578 | 579 | 580 | ## POST/child-lock 581 | 582 | Set status of the child lock. 583 | 584 | ### Body parameters 585 | 586 | | Field | Type | Description | 587 | | ----- | ---- | ----------------------------------- | 588 | | value | bool | the status of the child lock to set | 589 | 590 | ### Example 591 | 592 | #### Request 593 | 594 | - Postman: 595 | 596 | ```html 597 | GET http://{{heater_address}}/child-lock 598 | ``` 599 | 600 | Request body: 601 | 602 | ```json 603 | { 604 | "value": false 605 | } 606 | ``` 607 | 608 | 609 | #### Response 610 | 611 | ```json 612 | { 613 | "status": "ok" 614 | } 615 | ``` 616 | 617 | 618 | 619 | ## GET/open-window 620 | 621 | Return the current state of the open window functionality and its configuration parameters. 622 | 623 | ### Returned parameters 624 | 625 | | Field | Type | Description | 626 | | ------------------------------ | ----- | ------------------------------------------------------------ | 627 | | active_now | bool | true if open window functionality was activated and is active now | 628 | | drop_temperature_threshold | float | the required temperature drop to trigger (activate) the open window functionality (in Celsius degrees) | 629 | | drop_time_range | int | the time range when a drop of temperature will be expected (in seconds) | 630 | | enabled | bool | the state of the open window functionality, true if open window functionality is enabled | 631 | | increase_temperature_threshold | int | the time range when an increase of temperature will be expected (in seconds) | 632 | | max_time | int | the maximum time duration of the open window activeness | 633 | 634 | ### Example 635 | 636 | #### Request 637 | 638 | - Postman: 639 | 640 | ```html 641 | GET http://{{heater_address}}/open-window 642 | ``` 643 | 644 | Request body: empty 645 | 646 | 647 | #### Response 648 | 649 | ```json 650 | { 651 | "active_now": false, 652 | "drop_temperature_threshold": 5, 653 | "drop_time_range": 900, 654 | "enabled": true, 655 | "increase_temperature_threshold": 3, 656 | "increase_time_range": 900, 657 | "max_time": 3600, 658 | "status": "ok" 659 | } 660 | ``` 661 | 662 | 663 | 664 | ## POST/open-window 665 | 666 | Change the open window functionality parameters or enable/disable it. 667 | 668 | ### Body parameters 669 | 670 | | Field | Type | Description | 671 | | ------------------------------ | ----- | ------------------------------------------------------------ | 672 | | drop_temperature_threshold | float | the required temperature drop to trigger (activate) the open window functionality (in Celsius degrees) | 673 | | drop_time_range | int | the time range when a drop of temperature will be expected (in seconds) | 674 | | enabled | bool | the state of the open window functionality, true if open window functionality is enabled | 675 | | increase_temperature_threshold | int | the time range when an increase of temperature will be expected (in seconds) | 676 | | increase_time_range | float | the time range when an increase of temperature will be expected | 677 | | max_time | float | the maximum time duration of the open window activeness | 678 | 679 | ### Example 680 | 681 | #### Request 682 | 683 | - Postman: 684 | 685 | ```html 686 | POST http://{{heater_address}}/open-window 687 | ``` 688 | 689 | Request body: 690 | 691 | ```json 692 | { 693 | "drop_temperature_threshold": 5, 694 | "drop_time_range": 900, 695 | "enabled": true, 696 | "increase_temperature_threshold": 3, 697 | "increase_time_range": 900, 698 | "max_time": 3600 699 | } 700 | ``` 701 | 702 | 703 | #### Response 704 | 705 | ```json 706 | { 707 | "status": "ok" 708 | } 709 | ``` 710 | 711 | 712 | 713 | ## GET/weekly-program 714 | 715 | Return the weekly program. 716 | 717 | ### Returned parameters 718 | 719 | | Field | Type | Description | 720 | | ------ | ----------------- | ------------------------------------------------------------ | 721 | | active | bool | state of the weekly program: true if is active, if false, the device works as an independent device | 722 | | timers | list | repeating pairs of values. A single pair represents time and value when the temperature mode should be changed. Time is a week time, in minutes since Monday 00:00, when to switch to a specific temperature type (set in the second field of the pair) (see [ETemperatureType](#etemperaturetype)) | 723 | 724 | ### Example 725 | 726 | #### Request 727 | 728 | - Postman: 729 | 730 | ```html 731 | GET http://{{heater_address}}/weekly-program 732 | ``` 733 | 734 | Request body: empty 735 | 736 | - Curl: 737 | 738 | ```html 739 | curl -X GET -H "Content-Type: application/json" http://{{heater_address}}/weekly-program 740 | ``` 741 | 742 | 743 | #### Response 744 | 745 | ```json 746 | { 747 | "timers": [ 748 | { 749 | "name": "Comfort", 750 | "timestamp": 12 751 | }, 752 | { 753 | "name": "Away", 754 | "timestamp": 30 755 | }, 756 | { 757 | "name": "Sleep", 758 | "timestamp": 50 759 | } 760 | ], 761 | "active": false, 762 | "status": "ok" 763 | } 764 | ``` 765 | 766 | 767 | 768 | ## POST/weekly-program 769 | 770 | Set the weekly program or repeatable timers. One also needs to set the `timezone-offset`. The device needs to connect to the WiFi to synchronize the time with NTP server after each restart. 771 | 772 | To have the weekly program working, one needs to set `operation-mode` to `"Weekly program"` mode. 773 | 774 | To have the repeatable timers working, one needs to set `operation-mode` to `"Independent device"` mode. 775 | 776 | ### Body parameters 777 | 778 | | Field | Type | Description | 779 | | ------ | ----------------- | ------------------------------------------------------------ | 780 | | timers | list | repeating pairs of values. A single pair represents time and value when the temperature mode should be changed. Time is a week time, in minutes since Monday 00:00 when to switch to a specific temperature type (set in the second field of the pair). For available temperature types (see [GET set temperature)](#get-set-temperature) and [ETemperatureType](#etemperaturetype))| 781 | 782 | ### Example 783 | 784 | #### Request 785 | 786 | - Postman: 787 | 788 | ```html 789 | POST http://{{heater_address}}/weekly-program 790 | ``` 791 | 792 | Request body: 793 | 794 | ```json 795 | { 796 | "timers": [ 797 | { 798 | "name": "Comfort", 799 | "timestamp": 12 800 | }, 801 | { 802 | "name": "Away", 803 | "timestamp": 30 804 | }, 805 | { 806 | "name": "Sleep", 807 | "timestamp": 50 808 | } 809 | ] 810 | } 811 | ``` 812 | 813 | - Curl: 814 | 815 | ```html 816 | url -X POST -H "Content-Type: application/json" -d '{"timers": [{"name": "Comfort", "timestamp": 12},{"name": "Away", "timestamp": 30},{"name": "Sleep", "timestamp": 50}]}' http://{{heater_address}}/weekly-program 817 | ``` 818 | 819 | 820 | #### Response 821 | 822 | ```json 823 | { 824 | "status": "ok" 825 | } 826 | ``` 827 | 828 | 829 | 830 | ## GET/non-repeatable-timers 831 | 832 | Return the non-repeatable timers. 833 | 834 | ### Returned parameters 835 | 836 | | Field | Type | Description | 837 | | ------ | ----------------- | ------------------------------------------------------------ | 838 | | active | bool | true if operation mode is "Independent device" (see [EOprationMode](#eoprationmode)), false otherwise | 839 | | timers | list | repeating pairs of values. A single pair represents time and value when the temperature mode should be changed. Time defines when to switch to a specific temperature type (set in the second field of the pair). Time is as local unix timestamp, but in minutes, e.g. on 17.05.2021 the time is 27020801. | 840 | 841 | ### Example 842 | 843 | #### Request 844 | 845 | - Postman: 846 | 847 | ```html 848 | GET http://{{heater_address}}/non-repeatable-timers 849 | ``` 850 | 851 | Request body: empty 852 | 853 | 854 | #### Response 855 | 856 | ```json 857 | { 858 | "non_repeatable_timers": [ 859 | { 860 | "name": "Normal", 861 | "timestamp": 27245338 862 | }, 863 | { 864 | "name": "Off", 865 | "timestamp": 27245339 866 | }, 867 | { 868 | "name": "Normal", 869 | "timestamp": 27245340 870 | }, 871 | { 872 | "name": "Off", 873 | "timestamp": 27245341 874 | } 875 | ], 876 | "active": true, 877 | "status": "ok" 878 | } 879 | ``` 880 | 881 | 882 | 883 | ## POST/non-repeatable-timers 884 | 885 | Set the non-repeatable timers. 886 | 887 | 888 | One also needs to set the `timezone-offset`. The device needs to connect to the WiFi to synchronize the time with NTP server after each restart. 889 | To have the non-repeatable timers working, one needs to set `operation-mode` to `"Independent device"` mode. 890 | Please refer to example script `examples/python/timers.py` 891 | 892 | ### Body parameters 893 | 894 | | Field | Type | Description | 895 | | ------ | ----------------- | ------------------------------------------------------------ | 896 | | timers | list | A single pair represents time and value when the temperature mode should be changed. Time defines when to switch to a specific temperature type (set in the second field of the pair). Time is as local unix timestamp (so timezone is included), but in minutes, e.g. on 17.05.2021 the time is 27020801. Allowed temperature types for timers: "Normal", "Off", "AlwaysHeating" | 897 | 898 | ### Example 899 | 900 | #### Request 901 | 902 | - Postman: 903 | 904 | ```html 905 | POST http://{{heater_address}}/non-repeatable-timers 906 | ``` 907 | 908 | Request body: 909 | 910 | ```json 911 | { 912 | "non_repeatable_timers": [ 913 | { 914 | "name": "Off", 915 | "timestamp": 12 916 | }, 917 | { 918 | "name": "Away", 919 | "timestamp": 30 920 | }, 921 | { 922 | "name": "Sleep", " 923 | timestamp": 50 924 | } 925 | ] 926 | } 927 | ``` 928 | 929 | 930 | #### Response 931 | 932 | ```json 933 | { 934 | "status": "ok" 935 | } 936 | ``` 937 | 938 | 939 | 940 | ## GET/display-unit 941 | 942 | Return the current temperature units used on the display. 943 | 944 | ### Returned parameters 945 | 946 | | Field | Type | Description | 947 | | ----- | ------ | -------------------------------------------------------- | 948 | | value | string | the current temperature units: "Celsius" or "Fahrenheit" | 949 | 950 | ### Example 951 | 952 | #### Request 953 | 954 | - Postman: 955 | 956 | ```html 957 | GET http://{{heater_address}}/display-unit 958 | ``` 959 | 960 | Request body: empty 961 | 962 | 963 | #### Response 964 | 965 | ```json 966 | { 967 | "value": "Farenheit", 968 | "status": "ok" 969 | } 970 | ``` 971 | 972 | 973 | 974 | ## POST/display-unit 975 | 976 | Set the current temperature units used on the display. 977 | 978 | ### Body parameters 979 | 980 | | Field | Type | Description | 981 | | ----- | ------ | ------------------------------------------------------- | 982 | | value | string | the temperature units: "Celsius" or "Fahrenheit" to set | 983 | 984 | ### Example 985 | 986 | #### Request 987 | 988 | - Postman: 989 | 990 | ```html 991 | POST http://{{heater_address}}/child-lock 992 | ``` 993 | 994 | Request body: 995 | 996 | ```json 997 | { 998 | "value": "Farenheit" 999 | } 1000 | ``` 1001 | 1002 | 1003 | #### Response 1004 | 1005 | ```json 1006 | { 1007 | "status": "ok" 1008 | } 1009 | ``` 1010 | 1011 | 1012 | 1013 | ## GET/set-temperature 1014 | 1015 | Return temperature of the specified in body of the request temperature type. 1016 | In operation modes `Control individually` and `Independent device` one usally is interested in `Normal` temperature type. 1017 | 1018 | ### Returned parameters 1019 | 1020 | | Field | Type | Description | 1021 | | ----- | ----- | --------------------------------- | 1022 | | value | float | the temperature in Celsius to set | 1023 | 1024 | ### Body parameters 1025 | 1026 | | Field | Type | Description | 1027 | | ----- | ------ | ------------------------------------------------------------ | 1028 | | type | string | the temperature type to get (see [ETemperatureType](#etemperaturetype)) | 1029 | 1030 | ### Example 1031 | 1032 | #### Request 1033 | 1034 | - Postman: 1035 | 1036 | ```html 1037 | GET http://{{heater_address}}/set-temperature 1038 | ``` 1039 | 1040 | Request body: 1041 | 1042 | ```json 1043 | { 1044 | "type": "Normal" 1045 | } 1046 | ``` 1047 | 1048 | - Curl: 1049 | 1050 | ```html 1051 | curl -X GET -H "Content-Type: application/json" -d '{"type": "Normal"}' http://{{heater_address}}/set-temperature 1052 | ``` 1053 | 1054 | #### Response 1055 | 1056 | ```json 1057 | { 1058 | "value": 30, 1059 | "status": "ok" 1060 | } 1061 | ``` 1062 | 1063 | 1064 | 1065 | ## POST/set-temperature 1066 | 1067 | Set temperature of the specified temperature type. This endpoint doesn't put the device in specific mode, it just sets the temperature 1068 | for chosen mode. One cannot send "Off" type using this endpoint as temperature for Off mode cannot be set (it is set to specified value by default). 1069 | If operation mode is `"Control individually"` or `"Independent device"` one is usually interested in `"Normal"` temperature type. 1070 | 1071 | 1072 | ### Body parameters 1073 | 1074 | | Field | Type | Description | 1075 | | ----- | ------ | ------------------------------------------------------------ | 1076 | | type | string | the temperature type to set (see [ETemperatureType](#etemperaturetype)) | 1077 | | value | float | the temperature in Celsius to set | 1078 | 1079 | ### Example 1080 | 1081 | #### Request 1082 | 1083 | - Postman: 1084 | 1085 | ```html 1086 | POST http://{{heater_address}}/set-temperature 1087 | ``` 1088 | 1089 | Request body: 1090 | 1091 | ```json 1092 | { 1093 | "type": "Normal", 1094 | "value": 30 1095 | } 1096 | ``` 1097 | 1098 | - Curl: 1099 | 1100 | ```html 1101 | curl -X POST -H "Content-Type: application/json" -d '{"type": "Normal", "value": 30}' http://{{heater_address}}/set-temperature 1102 | ``` 1103 | 1104 | 1105 | #### Response 1106 | 1107 | ```json 1108 | { 1109 | "status": "ok" 1110 | } 1111 | ``` 1112 | 1113 | 1114 | 1115 | ## GET/oil-heater-power 1116 | 1117 | Return the max heating level in percentage of the nominal wattage. 1118 | Oil heater allows setting 3 different max power settings (40, 60 or 100% of the power), done by selecting number of active heating elements. 1119 | 1120 | ### Returned parameters 1121 | 1122 | | Field | Type | Description | 1123 | | ------------------------ | ---- | ------------------------------- | 1124 | | heating_level_percentage | int | the heating level in percentage | 1125 | 1126 | ### Example 1127 | 1128 | #### Request 1129 | 1130 | - Postman: 1131 | 1132 | ```html 1133 | GET http://{{heater_address}}/oil-heater-power 1134 | ``` 1135 | 1136 | Request body: empty 1137 | 1138 | 1139 | #### Response 1140 | 1141 | ```json 1142 | { 1143 | "value": 100, 1144 | "status": "ok" 1145 | } 1146 | ``` 1147 | 1148 | 1149 | 1150 | ## POST/oil-heater-power 1151 | 1152 | Set the max heating level in percentage of the nominal wattage. 1153 | Oil heater allows setting 3 different max power settings (40, 60 or 100% of the power), done by selecting number of active heating elements. 1154 | 1155 | ### Body parameters 1156 | 1157 | | Field | Type | Description | 1158 | | ------------------------ | ---- | -------------------------------------------------------- | 1159 | | heating_level_percentage | int | the heating level in percentage: 0, 40, 60 or 100 to set | 1160 | 1161 | ### Example 1162 | 1163 | #### Request 1164 | 1165 | - Postman: 1166 | 1167 | ```html 1168 | POST http://{{heater_address}}/oil-heater-power 1169 | ``` 1170 | 1171 | Request body: 1172 | 1173 | ```json 1174 | { 1175 | "heating_level_percentage": 100 1176 | } 1177 | ``` 1178 | 1179 | 1180 | #### Response 1181 | 1182 | ```json 1183 | { 1184 | "status": "ok" 1185 | } 1186 | ``` 1187 | 1188 | 1189 | 1190 | ## GET/predictive-heating-type 1191 | 1192 | Return the predictive heating type. 1193 | 1194 | ### Returned parameters 1195 | 1196 | | Field | Type | Description | 1197 | | ----------------------- | ------ | ------------------------------------------------------------ | 1198 | | predictive_heating_type | string | the predictive heating type (see [EPredictiveHeatingType](#epredictiveheatingtype)) | 1199 | 1200 | ### Example 1201 | 1202 | #### Request 1203 | 1204 | - Postman: 1205 | 1206 | ```html 1207 | GET http://{{heater_address}}/predictive-heating-type 1208 | ``` 1209 | 1210 | Request body: empty 1211 | 1212 | 1213 | #### Response 1214 | 1215 | ```json 1216 | { 1217 | "predictive_heating_type": "Off", 1218 | "status": "ok" 1219 | } 1220 | ``` 1221 | 1222 | 1223 | 1224 | ## POST/predictive-heating-type 1225 | 1226 | Set the predictive heating type. 1227 | 1228 | ### Body parameters 1229 | 1230 | | Field | Type | Description | 1231 | | ----------------------- | ------ | ------------------------------------------------------------ | 1232 | | predictive_heating_type | string | the predictive heating type (see [EPredictiveHeatingType](#epredictiveheatingtype)) to set | 1233 | 1234 | ### Example 1235 | 1236 | #### Request 1237 | 1238 | - Postman: 1239 | 1240 | ```html 1241 | POST http://{{heater_address}}/predictive-heating-type 1242 | ``` 1243 | 1244 | Request body: 1245 | 1246 | ```json 1247 | { 1248 | "predictive_heating_type": "Off" 1249 | } 1250 | ``` 1251 | 1252 | 1253 | #### Response 1254 | 1255 | ```json 1256 | { 1257 | "status": "ok" 1258 | } 1259 | ``` 1260 | 1261 | 1262 | 1263 | ## POST/overwrite-weekly-program 1264 | 1265 | Overwrite the weekly program. 1266 | 1267 | ### Body parameters 1268 | 1269 | | Field | Type | Description | 1270 | | -------- | ------ | ------------------------------------------------------------ | 1271 | | duration | int | the overwrite weekly program duration minutes | 1272 | | type | string | the temperature type to set (see [ETemperatureType](#etemperaturetype)) | 1273 | 1274 | ### Example 1275 | 1276 | #### Request 1277 | 1278 | - Postman: 1279 | 1280 | ```html 1281 | POST http://{{heater_address}}/overwrite-weekly-program 1282 | ``` 1283 | 1284 | Request body: 1285 | 1286 | ```json 1287 | { 1288 | "duration": 1, 1289 | "type": "Away" 1290 | } 1291 | ``` 1292 | 1293 | 1294 | #### Response 1295 | 1296 | ```json 1297 | { 1298 | "status": "ok" 1299 | } 1300 | ``` 1301 | 1302 | 1303 | 1304 | ## GET/vacation-mode 1305 | 1306 | Get the vacation mode settings. 1307 | 1308 | ### Returned parameters 1309 | 1310 | | Field | Type | Description | 1311 | | --------------- | ---- | ------------------------------- | 1312 | | start_timestamp | int | the 32 bit timestamp in minutes | 1313 | | end_timestamp | int | the 32 bit timestamp in minutes | 1314 | 1315 | ### Example 1316 | 1317 | #### Request 1318 | 1319 | - Postman: 1320 | 1321 | ```html 1322 | GET http://{{heater_address}}/vacation-mode 1323 | ``` 1324 | 1325 | Request body: empty 1326 | 1327 | 1328 | #### Response 1329 | 1330 | ```json 1331 | { 1332 | "start_timestamp": 0, 1333 | "end_timestamp": 0, 1334 | "status": "ok" 1335 | } 1336 | ``` 1337 | 1338 | 1339 | 1340 | ## POST/vacation-mode 1341 | 1342 | Set the vacation mode settings. 1343 | 1344 | ### Body parameters 1345 | 1346 | | Field | Type | Description | 1347 | | --------------- | ---- | ------------------------------------------------------------ | 1348 | | start_timestamp | int | the 32 bit timestamp in minutes (0 for no vacation mode) to set | 1349 | | end_timestamp | int | the 32 bit timestamp in minutes (0 for no vacation mode) to set | 1350 | 1351 | ### Example 1352 | 1353 | #### Request 1354 | 1355 | - Postman: 1356 | 1357 | ```html 1358 | POST http://{{heater_address}}/vacation-mode 1359 | ``` 1360 | 1361 | Request body: 1362 | 1363 | ```json 1364 | { 1365 | "start_timestamp": 0, 1366 | "end_timestamp": 0 1367 | } 1368 | ``` 1369 | 1370 | 1371 | #### Response 1372 | 1373 | ```json 1374 | { 1375 | "status": "ok" 1376 | } 1377 | ``` 1378 | 1379 | 1380 | 1381 | ## GET/timezone-offset 1382 | 1383 | Get the timezone offset. 1384 | 1385 | ### Returned parameters 1386 | 1387 | | Field | Type | Description | 1388 | | --------------- | ---- | ------------------------------------------------ | 1389 | | timezone_offset | int | the timezone offset in minutes from -840 to +720 | 1390 | 1391 | ### Example 1392 | 1393 | #### Request 1394 | 1395 | - Postman: 1396 | 1397 | ```Request body: empty 1398 | GET http://{{heater_address}}/timezone-offset 1399 | ``` 1400 | 1401 | Request body: empty 1402 | 1403 | 1404 | #### Response 1405 | 1406 | ```json 1407 | { 1408 | "timezone_offset": 1440, 1409 | "status": "ok" 1410 | } 1411 | ``` 1412 | 1413 | 1414 | 1415 | ## POST/timezone-offset 1416 | 1417 | Set the timezone offset. Required to have weekly program and timers working. 1418 | 1419 | ### Body parameters 1420 | 1421 | | Field | Type | Description | 1422 | | --------------- | ---- | ------------------------------------------------------------ | 1423 | | timezone_offset | int | Device timezone offset in minutes | 1424 | 1425 | ### Example 1426 | 1427 | #### Request 1428 | 1429 | - Postman: 1430 | 1431 | ```html 1432 | POST http://{{heater_address}}/timezone-offset 1433 | ``` 1434 | 1435 | Request body: 1436 | 1437 | ```json 1438 | { 1439 | "timezone_offset": 60 1440 | } 1441 | ``` 1442 | 1443 | 1444 | #### Response 1445 | 1446 | ```json 1447 | { 1448 | "status": "ok" 1449 | } 1450 | ``` 1451 | 1452 | 1453 | 1454 | ## POST/set-temperature-in-independent-mode-now 1455 | 1456 | Change temperature in independent mode now. Use values 0.0 and 99.0 to set ALWAYS_ON and ALWAYS_OFF, respectively. 1457 | Apart from changing value for some temperature type, in `"Independent device"` operation mode, one also needs to call this command to change the current temperature. 1458 | 1459 | ### Body parameters 1460 | 1461 | | Field | Type | Description | 1462 | | ----------- | ----- | ---------------------------- | 1463 | | temperature | float | the temperature value to set | 1464 | 1465 | ### Example 1466 | 1467 | #### Request 1468 | 1469 | - Postman: 1470 | 1471 | ```html 1472 | POST http://{{heater_address}}/set-temperature-in-independent-mode-now 1473 | ``` 1474 | 1475 | Request body: 1476 | 1477 | ```json 1478 | { 1479 | "temperature": 12.0 1480 | } 1481 | ``` 1482 | 1483 | 1484 | #### Response 1485 | 1486 | ```json 1487 | { 1488 | "status": "ok" 1489 | } 1490 | ``` 1491 | 1492 | 1493 | 1494 | ## GET/additional-socket-mode 1495 | 1496 | #### Only for socket heaters 1497 | 1498 | Return the additional socket mode. 1499 | 1500 | ### Returned parameters 1501 | 1502 | | Field | Type | Description | 1503 | | --------------- | ---- | -------------------------- | 1504 | | additional_mode | int | the additional socket mode | 1505 | 1506 | ### Example 1507 | 1508 | #### Request 1509 | 1510 | - Postman: 1511 | 1512 | ```html 1513 | GET http://{{heater_address}}/additional-socket-mode 1514 | ``` 1515 | 1516 | Request body: empty 1517 | 1518 | 1519 | #### Response 1520 | 1521 | ```json 1522 | { 1523 | "additional_mode": 3, 1524 | "status": "ok" 1525 | } 1526 | ``` 1527 | 1528 | 1529 | 1530 | ## POST/additional-socket-mode 1531 | 1532 | #### Only for socket heaters 1533 | 1534 | Set the additional socket mode. 1535 | 1536 | Body parameters 1537 | 1538 | | Field | Type | Description | 1539 | | --------------- | ---- | ---------------------------------- | 1540 | | additional_mode | int | the additional mode <0 - 4> to set | 1541 | 1542 | ### Example 1543 | 1544 | #### Request 1545 | 1546 | - Postman: 1547 | 1548 | ```html 1549 | POST http://{{heater_address}}/additional-socket-mode 1550 | ``` 1551 | 1552 | Request body: 1553 | 1554 | ```json 1555 | { 1556 | "additional_mode": 3 1557 | } 1558 | ``` 1559 | 1560 | 1561 | #### Response 1562 | 1563 | ```json 1564 | { 1565 | "status": "ok" 1566 | } 1567 | ``` 1568 | 1569 | 1570 | 1571 | ## GET/pid-parameters 1572 | 1573 | #### Only for panel heaters 1574 | 1575 | Return PID parameters of the temperature PID controller. 1576 | 1577 | ### Returned parameters 1578 | 1579 | | Field | Type | Description | 1580 | | ----------------------- | ----- | ------------------------------------------------ | 1581 | | kp | float | the proportional part gain | 1582 | | ki | float | the integral part gain | 1583 | | kd | float | the derivative part gain | 1584 | | kd_filter_N | float | the derivative filter time coefficient | 1585 | | windup_limit_percentage | float | the windup limit for integral part from 0 to 100 | 1586 | 1587 | ### Example 1588 | 1589 | #### Request 1590 | 1591 | - Postman: 1592 | 1593 | ```html 1594 | GET http://{{heater_address}}/pid-parameters 1595 | ``` 1596 | 1597 | Request body: empty 1598 | 1599 | 1600 | #### Response 1601 | 1602 | ```json 1603 | { 1604 | "kp": 70, 1605 | "ki": 0.02, 1606 | "kd": 4500, 1607 | "kd_filter_N": 60, 1608 | "windup_limit_percentage": 95, 1609 | "status": "ok" 1610 | } 1611 | ``` 1612 | 1613 | 1614 | 1615 | ## POST/pid-parameters 1616 | 1617 | #### Only for panel heaters 1618 | 1619 | Set PID parameters. Setting PID parameters will change current regulator type to PID. PID regulator works only with panel heater. 1620 | 1621 | ### Body parameters 1622 | 1623 | | Field | Type | Description | 1624 | | ----------------------- | ----- | ------------------------------------------------ | 1625 | | kp | float | the proportional part gain | 1626 | | ki | float | the integral part gain | 1627 | | kd | float | the derivative part gain | 1628 | | kd_filter_N | float | the derivative filter time coefficient | 1629 | | windup_limit_percentage | float | the windup limit for integral part from 0 to 100 | 1630 | 1631 | ### Example 1632 | 1633 | #### Request 1634 | 1635 | - Postman: 1636 | 1637 | ```html 1638 | POST http://{{heater_address}}/pid-parameters 1639 | ``` 1640 | 1641 | Request body: 1642 | 1643 | ```json 1644 | { 1645 | "kp": 70, 1646 | "ki": 0.02, 1647 | "kd": 4500, 1648 | "kd_filter_N": 60, 1649 | "windup_limit_percentage": 95, 1650 | "status": "ok" 1651 | } 1652 | ``` 1653 | 1654 | 1655 | #### Response 1656 | 1657 | ```json 1658 | { 1659 | "status": "ok" 1660 | } 1661 | ``` 1662 | 1663 | 1664 | 1665 | ## GET/cloud-communication 1666 | 1667 | Return the cloud communication activeness status. 1668 | 1669 | ### Returned parameters 1670 | 1671 | | Field | Type | Description | 1672 | | ----- | ---- | ------------------------------------------------------------ | 1673 | | value | bool | the cloud communication activeness status, true if device is allowed to communicate with cloud | 1674 | 1675 | ### Example 1676 | 1677 | #### Request 1678 | 1679 | - Postman: 1680 | 1681 | ```html 1682 | GET http://{{heater_address}}/cloud-communication 1683 | ``` 1684 | 1685 | Request body: empty 1686 | 1687 | 1688 | #### Response 1689 | 1690 | ```json 1691 | { 1692 | "value": true, 1693 | "status": "ok" 1694 | } 1695 | ``` 1696 | 1697 | 1698 | 1699 | ## POST/cloud-communication 1700 | 1701 | Allows disabling cloud communication completely. Requires a reboot after this command. 1702 | 1703 | ### Body parameters 1704 | 1705 | | Field | Type | Description | 1706 | | ----- | ---- | ------------------------------------------------------------ | 1707 | | value | bool | the cloud communication activeness status, true if device is allowed to communicate with cloud | 1708 | 1709 | ### Example 1710 | 1711 | #### Request 1712 | 1713 | - Postman: 1714 | 1715 | ```html 1716 | POST http://{{heater_address}}/cloud-communication 1717 | ``` 1718 | 1719 | Request body: 1720 | 1721 | ```json 1722 | { 1723 | "value": false 1724 | } 1725 | ``` 1726 | 1727 | 1728 | #### Response 1729 | 1730 | ```json 1731 | { 1732 | "status": "ok" 1733 | } 1734 | ``` 1735 | 1736 | 1737 | 1738 | ## POST/ota-update 1739 | 1740 | Perform OTA update, to replace the firmware. The device needs to have Internet access to perform it. 1741 | 1742 | ### Body parameters 1743 | 1744 | | Field | Type | Description | 1745 | | ------- | ------------ | ------------------------------------------------------------ | 1746 | | address | string (url) | the address to firmware binary for the heater, http address allowed | 1747 | 1748 | ### Example 1749 | 1750 | #### Request 1751 | 1752 | - Postman: 1753 | 1754 | ```html 1755 | POST http://{{heater_address}}/ota-update 1756 | ``` 1757 | 1758 | Request body: 1759 | 1760 | ```json 1761 | { 1762 | "value": false 1763 | } 1764 | ``` 1765 | 1766 | 1767 | #### Response 1768 | 1769 | ```json 1770 | { 1771 | "status": "ok" 1772 | } 1773 | ``` 1774 | 1775 | 1776 | 1777 | ## GET/config-parameter 1778 | 1779 | Return the configuration parameter determined by the name in request message. 1780 | 1781 | ### Body parameters 1782 | 1783 | | Field | Type | Description | 1784 | | ----- | ------ | -------------------------------- | 1785 | | name | string | the name of the parameter to get | 1786 | 1787 | ### Returned parameters 1788 | 1789 | | Field | Type | Description | 1790 | | ----- | ------ | -------------------------- | 1791 | | value | string | the value of the parameter | 1792 | 1793 | ### Example 1794 | 1795 | #### Request 1796 | 1797 | - Postman: 1798 | 1799 | ```html 1800 | GET http://{{heater_address}}/config-parameter 1801 | ``` 1802 | 1803 | Request body: 1804 | 1805 | ```json 1806 | { 1807 | "name": "Set" 1808 | } 1809 | ``` 1810 | 1811 | 1812 | #### Response 1813 | 1814 | ```json 1815 | { 1816 | "value": "", 1817 | "status": "ok" 1818 | } 1819 | ``` 1820 | 1821 | 1822 | 1823 | ## POST/config-parameter 1824 | 1825 | Set the configuration parameter determined by the name in request message. 1826 | 1827 | ### Body parameters 1828 | 1829 | | Field | Type | Description | 1830 | | ----- | ------ | -------------------------------- | 1831 | | name | string | the name of the parameter to set | 1832 | | vaule | string | the value of the parameter | 1833 | 1834 | ### Example 1835 | 1836 | #### Request 1837 | 1838 | - Postman: 1839 | 1840 | ```html 1841 | POST http://{{heater_address}}/cloud-communication 1842 | ``` 1843 | 1844 | Request body: 1845 | 1846 | ```json 1847 | { 1848 | "name": "Set", 1849 | "value": 70 1850 | } 1851 | ``` 1852 | 1853 | 1854 | #### Response 1855 | 1856 | ```json 1857 | { 1858 | "status": "ok" 1859 | } 1860 | ``` 1861 | 1862 | 1863 | 1864 | ## POST/max-heater-power 1865 | 1866 | Set max heater power in Watts. 1867 | 1868 | ### Body parameters 1869 | 1870 | | Field | Type | Description | 1871 | | --------- | ---- | -------------------------------------------------- | 1872 | | power | int | the value of the heater power in Watts | 1873 | | calibrate | bool | whether to perform the calibration with the chip measuring the power usage | 1874 | 1875 | ### Example 1876 | 1877 | #### Request 1878 | 1879 | - Postman: 1880 | 1881 | ```html 1882 | POST http://{{heater_address}}/max-heater-power 1883 | ``` 1884 | 1885 | Request body: 1886 | 1887 | ```json 1888 | { 1889 | "power": 12, 1890 | "calibrate": false 1891 | } 1892 | ``` 1893 | 1894 | 1895 | #### Response 1896 | 1897 | ```json 1898 | { 1899 | "status": "ok" 1900 | } 1901 | ``` 1902 | 1903 | 1904 | 1905 | ## POST/ablecloud-message 1906 | 1907 | Send a message and process it as if it would come from AbleCloud module. 1908 | 1909 | ### Body parameters 1910 | 1911 | | Field | Type | Description | 1912 | | ------------ | ------ | ------------------------------------------------------------ | 1913 | | message_code | int | code of the message | 1914 | | data | string | the binary data as hex string, e.g. string "1AB2550C" would be parsed to binary array {0x1A, 0xB2, 0x55, 0x0C} | 1915 | 1916 | ### Example 1917 | 1918 | #### Request 1919 | 1920 | - Postman: 1921 | 1922 | ```html 1923 | POST http://{{heater_address}}/ablecloud-message 1924 | ``` 1925 | 1926 | Request body: 1927 | 1928 | ```json 1929 | { 1930 | "message_code": 3, 1931 | "data": 4443 1932 | } 1933 | ``` 1934 | 1935 | 1936 | #### Response 1937 | 1938 | ```json 1939 | { 1940 | "status": "ok" 1941 | } 1942 | ``` 1943 | 1944 | 1945 | ## GET/scan-wifi 1946 | 1947 | The heater has to be configured in the access mode (AP) mode. Then, you have to be connected to the network provided by your heater and check the IP adress which has format "192.168.4.x". The request should be post on this address. 1948 | 1949 | Returns the list of WiFi networks scanned by ESP32, ordered by best signal (maximum 20 networks). 1950 | 1951 | ### Returned parameters 1952 | 1953 | | Field | Type | Description | 1954 | | ----- | ---- | ------------------------------------------ | 1955 | | wifi | list | the list of WiFi networks scanned by ESP32 | 1956 | 1957 | ### Example 1958 | 1959 | #### Request 1960 | 1961 | - Postman: 1962 | 1963 | ```html 1964 | GET http://192.168.4.x/scan-wifi 1965 | ``` 1966 | 1967 | Request body: empty 1968 | 1969 | 1970 | #### Response 1971 | 1972 | ```json 1973 | { 1974 | "value": "", 1975 | "status": "ok" 1976 | } 1977 | ``` 1978 | 1979 | 1980 | 1981 | ## POST/device-config 1982 | 1983 | The heater has to be configured in the access mode (AP) mode. Then, you have to be connected to the network provided by your heater and check the IP adress which has format "192.168.4.x". The request should be post on this address. Post the device configuration, same as the one can be done via BLE. 1984 | 1985 | ### Body parameters 1986 | 1987 | | Field | Type | Description | 1988 | | ------------------- | ------ | ------------------------------------------------------------ | 1989 | | ssid | string | the SSID of the WiFi | 1990 | | password | string | the password of the WiFi | 1991 | | connectivity_option | string | the connectivity option (see [ECloudAndServerCommunicationType](#ecloudandservercommunicationtype)) | 1992 | 1993 | ### Example 1994 | 1995 | #### Request 1996 | 1997 | - Postman: 1998 | 1999 | ```html 2000 | POST http://{{heater_address}}/device-config 2001 | ``` 2002 | 2003 | Request body: 2004 | 2005 | ```json 2006 | { 2007 | "ssid": "wifi_ssid", 2008 | "password": "wifi_password", 2009 | "connectivity_option": "sta_cloud_and_local_api" 2010 | } 2011 | ``` 2012 | 2013 | 2014 | #### Response 2015 | 2016 | ```json 2017 | { 2018 | "status": "ok" 2019 | } 2020 | ``` 2021 | 2022 | ## GET/hysteresis-parameters 2023 | Get current hysteresis setting. 2024 | 2025 | ### Returned parameters 2026 | 2027 | | Field | Type | Description | 2028 | | --------------------- | ----- | -------------------------------------------- | 2029 | | temp_hysteresis_upper | float | upper offset (set temp + this -> stop heat) | 2030 | | temp_hysteresis_lower | float | lower offset (set temp - this -> start heat) | 2031 | 2032 | ### Example 2033 | 2034 | #### Request 2035 | 2036 | - Postman: 2037 | 2038 | ```html 2039 | GET http://192.168.4.x/hysteresis-parameters 2040 | ``` 2041 | 2042 | Request body: empty 2043 | 2044 | 2045 | #### Response 2046 | 2047 | ```json 2048 | { 2049 | "temp_hysteresis_upper": 2, 2050 | "temp_hysteresis_lower": 1, 2051 | "regulator_type": "hysteresis", 2052 | "status": "ok" 2053 | } 2054 | ``` 2055 | 2056 | 2057 | ## POST/hysteresis-parameters 2058 | Set hysteresis parameters. Setting hysteresis parameters will change current regulator type to hystersis. 2059 | 2060 | AFTER CHANGING HYSTERESIS PARAMETERS RESTART IS REQUIRED 2061 | 2062 | ### Body parameters 2063 | 2064 | | Field | Type | Description | 2065 | | --------------------- | ----- | -------------------------------------------- | 2066 | | temp_hysteresis_upper | float | upper offset (set temp + this -> stop heat) | 2067 | | temp_hysteresis_lower | flaot | lower offset (set temp - this -> start heat) | 2068 | 2069 | ### Example 2070 | 2071 | #### Request 2072 | 2073 | - Postman: 2074 | 2075 | ```html 2076 | POST http://{{heater_address}}/hysteresis-parameters 2077 | ``` 2078 | 2079 | Request body: 2080 | 2081 | ```json 2082 | { 2083 | "temp_hysteresis_upper": 1, 2084 | "temp_hysteresis_lower": 1, 2085 | } 2086 | ``` 2087 | 2088 | 2089 | #### Response 2090 | 2091 | ```json 2092 | { 2093 | "status": "ok" 2094 | } 2095 | ``` 2096 | 2097 | 2098 | ## GET/limited-heating-power 2099 | Get current maximum limited heating power (percentage of maximum power) (only Panel and Storage heater). 2100 | 2101 | #### Only for panel heaters 2102 | 2103 | ### Returned values 2104 | 2105 | | Field | Type | Description | 2106 | | - | - | - | 2107 | | limited_heating_power | int | percentage of maximum power that heater can use. Value in range 10 - 100. | 2108 | | status | str | "ok" or error message | 2109 | 2110 | ### Example 2111 | 2112 | #### Request 2113 | 2114 | - Postman: 2115 | 2116 | ```html 2117 | GET http://{{heater_address}}/limited-heating-power 2118 | ``` 2119 | 2120 | #### Response 2121 | ```json 2122 | { 2123 | "limited_heating_power": 75, 2124 | "status": "ok" 2125 | } 2126 | ``` 2127 | 2128 | 2129 | ## POST/limited-heating-power 2130 | 2131 | #### Only for panel heaters 2132 | 2133 | Set current maximum limited heating power (percentage of maximum power) (only Panel and Storage heater). 2134 | 2135 | ### Body parameters 2136 | 2137 | | Field | Type | Description | 2138 | | --------------------- | ----- | -------------------------------------------- | 2139 | | limited_heating_power | int | percentage of maximum power that heater can use. Value in range 10 - 100. | 2140 | 2141 | ### Example 2142 | 2143 | #### Request 2144 | 2145 | - Postman: 2146 | 2147 | ```html 2148 | POST http://{{heater_address}}/limited-heating-power 2149 | ``` 2150 | 2151 | Request body: 2152 | 2153 | ```json 2154 | { 2155 | "limited_heating_power": 75, 2156 | } 2157 | ``` 2158 | 2159 | #### Response 2160 | 2161 | ```json 2162 | { 2163 | "status": "ok" 2164 | } 2165 | ``` 2166 | 2167 | ## GET/controller-type 2168 | Get current current regulator controller type. Hysteresis controller is available for oil, convertor and socket heaters. Slow PID is available for panel and storage heaters. 2169 | 2170 | ### Returned values 2171 | 2172 | | Field | Type | Description | 2173 | | - | - | - | 2174 | | regulator_type | str | type of current controller type ("pid" or "hysteresis_or_slow_pid") | 2175 | | status | str | "ok" or error message | 2176 | 2177 | ### Example 2178 | 2179 | #### Request 2180 | 2181 | - Postman: 2182 | 2183 | ```html 2184 | GET http://{{heater_address}}/controller-type 2185 | ``` 2186 | 2187 | #### Response 2188 | ```json 2189 | { 2190 | "regulator_type": "hysteresis_or_slow_pid", 2191 | "status": "ok" 2192 | } 2193 | ``` 2194 | 2195 | ## POST/controller-type 2196 | Set current current regulator controller type. Hysteresis controller is available for oil, convertor and socket heaters. Slow PID is available for panel and storage heaters. 2197 | 2198 | ### Body parameters 2199 | 2200 | | Field | Type | Description | 2201 | | ----- | ---- | ----------- | 2202 | | regulator_type | str | type of current controller type ("pid", "hysteresis_or_slow_pid" or "unknown" - no change) | 2203 | 2204 | ### Example 2205 | 2206 | #### Request 2207 | 2208 | - Postman: 2209 | 2210 | ```html 2211 | POST http://{{heater_address}}/controller-type 2212 | ``` 2213 | 2214 | Request body: 2215 | 2216 | ```json 2217 | { 2218 | "regulator_type": "unknown", 2219 | } 2220 | ``` 2221 | 2222 | #### Response 2223 | 2224 | ```json 2225 | { 2226 | "status": "ok" 2227 | } 2228 | ``` 2229 | 2230 | ## POST/set-custom-name 2231 | Change your device's custom name. 2232 | 2233 | ### Body parameters 2234 | 2235 | | Field | Type | Description | 2236 | | ----- | ---- | ----------- | 2237 | | device_name | str | new device custom name, it can have at most 32 characters | 2238 | 2239 | ### Example 2240 | 2241 | #### Request 2242 | 2243 | - Postman: 2244 | 2245 | ```html 2246 | POST http://{{heater_address}}/set-custom-name 2247 | ``` 2248 | 2249 | Request body: 2250 | 2251 | ```json 2252 | { 2253 | "device_name": "My new custom name", 2254 | } 2255 | ``` 2256 | 2257 | #### Response 2258 | 2259 | ```json 2260 | { 2261 | "status": "ok" 2262 | } 2263 | ``` 2264 | 2265 | ## POST/increase-set-temperature 2266 | Increase set temperature by one 0.5\*C. 2267 | 2268 | ### Body parameters 2269 | 2270 | None 2271 | 2272 | ### Example 2273 | 2274 | #### Request 2275 | 2276 | - Postman: 2277 | 2278 | ```html 2279 | POST http://{{heater_address}}/increase-set-temperature 2280 | ``` 2281 | 2282 | Request body: 2283 | 2284 | None 2285 | 2286 | #### Response 2287 | 2288 | ```json 2289 | { 2290 | "status": "ok" 2291 | } 2292 | ``` 2293 | 2294 | ## POST/decrease-set-temperature 2295 | Decrease set temperature by 0.5\*C. 2296 | 2297 | ### Body parameters 2298 | 2299 | None 2300 | 2301 | ### Example 2302 | 2303 | #### Request 2304 | 2305 | - Postman: 2306 | 2307 | ```html 2308 | POST http://{{heater_address}}/decrease-set-temperature 2309 | ``` 2310 | 2311 | Request body: 2312 | 2313 | None 2314 | 2315 | #### Response 2316 | 2317 | ```json 2318 | { 2319 | "status": "ok" 2320 | } 2321 | ``` 2322 | 2323 | ## POST/set-api-key 2324 | Set API key to authenticate users. BE CAREFULL!!! To reset API key one need to perform factory reset. 2325 | 2326 | ### Body parameters 2327 | 2328 | | Field | Type | Description | 2329 | | ----- | ---- | ----------- | 2330 | | api_key | str | new API key, enables authentication and HTTPS server, it can have at most 63 characters | 2331 | 2332 | ### Example 2333 | 2334 | #### Request 2335 | 2336 | - Postman: 2337 | 2338 | ```html 2339 | POST http://{{heater_address}}/set-api-key 2340 | ``` 2341 | 2342 | Request body: 2343 | 2344 | ```json 2345 | { 2346 | "api_key": "asdasd" 2347 | } 2348 | ``` 2349 | 2350 | #### Response 2351 | 2352 | ```json 2353 | { 2354 | "status": "ok" 2355 | } 2356 | ``` 2357 | 2358 | ## GET/commercial-lock-customization 2359 | Get commercial lock with range of possible temperature to change. 2360 | 2361 | ### Returned values 2362 | 2363 | | Field | Type | Description | 2364 | | - | - | - | 2365 | | enable | bool | sets commercial lock state | 2366 | | min_allowed_temp_in_commercial_lock | float | minimal temperature that can be set while device has active commercial lock | 2367 | | max_allowed_temp_in_commercial_lock | float | maximal temperature that can be set while device has active commercial lock | 2368 | 2369 | ### Example 2370 | 2371 | #### Request 2372 | 2373 | - Postman: 2374 | 2375 | ```html 2376 | GET http://{{heater_address}}/commercial-lock-customization 2377 | ``` 2378 | 2379 | #### Response 2380 | ```json 2381 | { 2382 | "enabled": false, 2383 | "min_allowed_temp_in_commercial_lock": 11, 2384 | "max_allowed_temp_in_commercial_lock": 30, 2385 | "status": "ok" 2386 | } 2387 | ``` 2388 | 2389 | ## POST/commercial-lock-customization 2390 | Set commercial lock with range of possible temperature to change. 2391 | 2392 | ### Body parameters 2393 | 2394 | | Field | Type | Description | 2395 | | ----- | ---- | ----------- | 2396 | | enable | bool | sets commercial lock state | 2397 | | min_allowed_temp_in_commercial_lock | float | minimal temperature that can be set while device has active commercial lock | 2398 | | max_allowed_temp_in_commercial_lock | float | maximal temperature that can be set while device has active commercial lock | 2399 | ### Example 2400 | 2401 | #### Request 2402 | 2403 | - Postman: 2404 | 2405 | ```html 2406 | POST http://{{heater_address}}/commercial-lock-customization 2407 | ``` 2408 | 2409 | Request body: 2410 | 2411 | ```json 2412 | { 2413 | "enabled": false, 2414 | "min_allowed_temp_in_commercial_lock": 11, 2415 | "max_allowed_temp_in_commercial_lock": 30 2416 | } 2417 | ``` 2418 | 2419 | #### Response 2420 | 2421 | ```json 2422 | { 2423 | "status": "ok" 2424 | } 2425 | ``` 2426 | 2427 | 2428 | 2429 | 2430 | 2431 | ## Fields 2432 | 2433 | ### ELockStatus 2434 | 2435 | The ELockStatus variable allow to set one of the following lock mode: 2436 | 2437 | | Value | Description | 2438 | | ----------------- | ------------------------------------------------------------ | 2439 | | "No lock" | all buttons are active | 2440 | | "Child lock" | buttons on the device not active. In order to activate the child lock please turn on the heater and before 5 seconds pass, press the settings button for 3 seconds and release. | 2441 | | "Commercial lock" | buttons on the device not active. In order to activate the commercial lock please turn on the heater and before 10 seconds pass, press the settings button for 3 seconds and release. | 2442 | 2443 | ### EOpenWindowStatus 2444 | 2445 | The Open Windows function is activated instantly when temperature drops within `x1` min by `x2` degrees 2446 | or more. The heater will automatically stop heating and `FO` will be displayed on in the display 2447 | of the heater. The heater will automatically start heating again if temperature will increase at 2448 | least by `x3` degrees within `x4` minutes. 2449 | 2450 | | Value | Description | 2451 | | ------------------------- | ------------- | 2452 | | "Disabled not active now" | Open Windows functionality is disabled, so it is not working at all | 2453 | | "Enabled active now" | Open Window functionality is active, but the window is not detected as open, so the heater operates normally | 2454 | | "Enabled not active now" | Open Window functionality is active, and the window is detected as open, so the heater is not heating | 2455 | 2456 | ### EOprationMode 2457 | 2458 | The Heater may operate in four operation modes: 2459 | 2460 | | Value | Description | 2461 | | ---------------------- | ------------------------------------------------------------ | 2462 | | "Off" | the device is in off mode, it is not possible to send any comands to the device. The device doesn't follow neither weekly program nor it is in independent mode, nor in control individually | 2463 | | "Weekly program" | follow the weekly program, changing temperature by display buttons changes the temperature of the current temperature mode | 2464 | | "Independent device" | follow the single set value, with timers enabled | 2465 | | "Control individually" | follow the single set value, but not use any timers or weekly program | 2466 | | "Invalid" | | 2467 | 2468 | ### ETemperatureType 2469 | 2470 | | Value | Description | 2471 | | --------- | ------------------------------------------------------------ | 2472 | | "Off" | The temperature is set to default value of 0 (so that heater will not heat at all) that cannot be changed by the user. As one cannot set temperature for this type, it cannot be sent through set-temperature endpoint | 2473 | | "Normal" | a single value, used for operation modes "Independent device" and timers | 2474 | | "Comfort" | Temperature defined for type Comfort | 2475 | | "Sleep" | Temperature defined for type Sleep | 2476 | | "Away" | Temperature defined for type Away | 2477 | | "AlwaysHeating" | Heat all the time, regardless of the temperature. One cannot set temperature for this type. | 2478 | 2479 | In weekly program one can set all of these types. 2480 | For timers, one can set only "Normal", "Off", "AlwaysHeating" types. 2481 | 2482 | 2483 | ### EPredictiveHeatingType 2484 | 2485 | Defines type of predictive heating functionality. 2486 | 2487 | | Value | Description | 2488 | | --------- | ------------- | 2489 | | "Off" | No predictive heating. Temperature will be change exactly with the weekly program timer | 2490 | | "Simple" | Simple predictive heating. Temperature will be change before the timer, with a fixed time for each Celsius degree | 2491 | | "Advanced" | Advanced predictive heating. Temperature will be change before the timer, with a time based on the current room model. Model is estimated while running. | 2492 | 2493 | ### ECloudAndServerCommunicationType 2494 | 2495 | Defines how the device communicated via WiFi and cloud. 2496 | 2497 | | Value | Description | 2498 | | ----------------------------- | ------------- | 2499 | | "sta_cloud_without_local_api" | Device connects to the router. Cloud is enabled, but this WiFi API is disabled | 2500 | | "sta_cloud_and_local_api" | Device connects to the router. Cloud and this WiFi API both enabled | 2501 | | "sta_local_api_without_cloud" | Device connects to the router. Cloud is disabled, but this WiFi API is enabled | 2502 | | "ap_local_api_without_cloud" | Device behaves as Access Point. One can connect to the device via WiFi and communicate through this WiFi API| 2503 | 2504 | -------------------------------------------------------------------------------- /heaters/examples/bash/query_ambient_temperature.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | HEATER_ADDRESS="10.0.0.102" 4 | 5 | while : 6 | do 7 | result=$(curl -s -X GET http://${HEATER_ADDRESS}/control-status) 8 | echo $result | grep -Po '"ambient_temperature": [.0-9]*' 9 | sleep 1 10 | done 11 | 12 | -------------------------------------------------------------------------------- /heaters/examples/python/authentication_and_HTTP.py: -------------------------------------------------------------------------------- 1 | import time 2 | import requests 3 | 4 | IP_DEVICE = "192.168.8.151" 5 | 6 | PROTOCOL_HTTP = "http://" 7 | PROTOCOL_HTTPS = "https://" 8 | 9 | ENDPOINT_STATUS = "/status" 10 | ENDPOINT_SET_API_KEY = "/set-api-key" 11 | 12 | AUTHENTICATION_KEY = "SeCrEt_K3Y" 13 | 14 | 15 | # Product runs HTTP server - no authentication or encryption 16 | url = PROTOCOL_HTTP + IP_DEVICE + ENDPOINT_STATUS 17 | r = requests.get(url=url) 18 | print(r.status_code) 19 | print(r.text) 20 | 21 | time.sleep(2) 22 | 23 | # Product runs HTTP server - no authentication or encryption 24 | url = PROTOCOL_HTTP + IP_DEVICE + ENDPOINT_SET_API_KEY 25 | try: 26 | r = requests.post(url=url, json={"api_key": AUTHENTICATION_KEY}, timeout=5.0) 27 | except requests.exceptions.ReadTimeout: 28 | print("Timeout on POST /set-api-key. Everything is all right") 29 | # There is no response because product needs to be restarted. After restart HTTPS server will be started. 30 | # Every request from now on will have to contain "Authentication" header with AUTHENTICATION_KEY as value 31 | # print(r.status_code) 32 | # print(r.text) 33 | pass 34 | except Exception as e: 35 | print(f"Other error {e}") 36 | exit(1) 37 | 38 | time.sleep(2) 39 | 40 | url = PROTOCOL_HTTPS + IP_DEVICE + ENDPOINT_STATUS 41 | r = requests.get(url=url, headers={"Authentication": AUTHENTICATION_KEY}, verify=False) 42 | print(r.status_code) 43 | print(r.text) 44 | 45 | 46 | -------------------------------------------------------------------------------- /heaters/examples/python/basic_control.py: -------------------------------------------------------------------------------- 1 | """ 2 | This example queries the current control status to obtain current temperature 3 | and control signal (how much the heater is heating). 4 | Then it changes the set temperature every minute. 5 | """ 6 | 7 | import sys 8 | import time 9 | 10 | try: 11 | import requests 12 | except ImportError: 13 | print("ERROR! Please install requests library! Run `pip3 install requests` and retry!", file=sys.stderr) 14 | sys.exit(-1) 15 | 16 | 17 | HEATER_ADDRESS = "10.0.0.176" # Please specify IP address of your device here 18 | 19 | 20 | def get_control_status_and_print_it(): 21 | response = requests.get(url=f'http://{HEATER_ADDRESS}/control-status', timeout=5) 22 | if response.status_code != 200: 23 | raise Exception(f"Request error! Body={response.text}") 24 | 25 | control_status = response.json() 26 | 27 | ambient_temperature = control_status['ambient_temperature'] 28 | set_temperature = control_status['set_temperature'] 29 | control_signal = control_status['control_signal'] 30 | current_power = control_status['current_power'] 31 | 32 | print(f"STATUS:" 33 | f" Ambient temperature = {ambient_temperature:.2f}\n" 34 | f" Set temperature = {set_temperature:.1f}\n" 35 | f" Control signal = {control_signal} %\n" 36 | f" Current power = {current_power} W\n") 37 | 38 | 39 | def set_normal_operation_mode(): 40 | # because the device may be running in weekly program - so make sure it is not 41 | payload = {'mode': 'Control individually'} 42 | response = requests.post(url=f'http://{HEATER_ADDRESS}/operation-mode', json=payload, timeout=5) 43 | if response.status_code != 200: 44 | raise Exception(f"Request error! Body={response.text}") 45 | 46 | 47 | def change_temperature(temperature): 48 | payload = {'type': 'Normal', 'value': temperature} 49 | response = requests.post(url=f'http://{HEATER_ADDRESS}/set-temperature', json=payload, timeout=5) 50 | if response.status_code != 200: 51 | raise Exception(f"Request error! Body={response.text}") 52 | 53 | 54 | def main(): 55 | get_control_status_and_print_it() 56 | 57 | set_normal_operation_mode() 58 | 59 | for i in range(3): 60 | print('===========') 61 | target_temperature = 15 + i / 2 62 | print(f'Changing the set temperature to {target_temperature:.1f} C...') 63 | change_temperature(temperature=target_temperature) 64 | time.sleep(1) 65 | get_control_status_and_print_it() 66 | time.sleep(1) 67 | 68 | 69 | if __name__ == '__main__': 70 | main() 71 | print('Done!') 72 | 73 | 74 | ''' 75 | EXAMPLE OUTPUT: 76 | STATUS: Ambient temperature = 21.24 77 | Set temperature = 32.0 78 | Control signal = 100 % 79 | Current power = 1000 W 80 | 81 | =========== 82 | Changing the set temperature to 15.0 C... 83 | STATUS: Ambient temperature = 21.26 84 | Set temperature = 15.0 85 | Control signal = 0 % 86 | Current power = 0 W 87 | 88 | =========== 89 | Changing the set temperature to 15.5 C... 90 | STATUS: Ambient temperature = 21.25 91 | Set temperature = 15.5 92 | Control signal = 0 % 93 | Current power = 0 W 94 | 95 | =========== 96 | Changing the set temperature to 16.0 C... 97 | STATUS: Ambient temperature = 21.28 98 | Set temperature = 16.0 99 | Control signal = 0 % 100 | Current power = 0 W 101 | 102 | Done! 103 | ''' 104 | -------------------------------------------------------------------------------- /heaters/examples/python/temperature_control.py: -------------------------------------------------------------------------------- 1 | """ 2 | This example queries the status of the status device 3 | and set and get the temperature in a given temperature type. 4 | Then it changes the set temperature every minute. 5 | """ 6 | 7 | import sys 8 | import time 9 | 10 | try: 11 | import requests 12 | except ImportError: 13 | print("ERROR! Please install requests library! Run `pip3 install requests` and retry!", file=sys.stderr) 14 | sys.exit(-1) 15 | 16 | 17 | HEATER_ADDRESS = "10.0.0.176" # Please specify IP address of your device here 18 | 19 | 20 | def print_device_status(): 21 | response = requests.get(url=f'http://{HEATER_ADDRESS}/status') 22 | if response.status_code != 200: 23 | raise Exception(f"Request error! Body={response.text}") 24 | 25 | device_status = response.json() 26 | 27 | name = device_status['name'] 28 | version = device_status['version'] 29 | operation_key = device_status['operation_key'] 30 | 31 | print(f"STATUS:\n" 32 | f" Name = {name}\n" 33 | f" Version = {version}\n" 34 | f" Operation key = {operation_key} \n") 35 | 36 | 37 | def set_temperature_value_for_type(temperature_type, temperature): 38 | payload = {'type': temperature_type, 'value': temperature} 39 | response = requests.post(url=f'http://{HEATER_ADDRESS}/set-temperature', json=payload, timeout=5) 40 | if response.status_code != 200: 41 | raise Exception(f"Request error! Body={response.text}") 42 | 43 | 44 | def get_temperature_value_for_temperature_type(temperature_type): 45 | payload = {'type': temperature_type} 46 | response = requests.get(url=f'http://{HEATER_ADDRESS}/set-temperature', json=payload, timeout=5) 47 | if response.status_code != 200: 48 | raise Exception(f"Request error! Body={response.text}") 49 | 50 | temperature = response.json() 51 | set_temperature = temperature['value'] 52 | 53 | print(f"set_temperature = {set_temperature:.2f}\n") 54 | 55 | 56 | def main(): 57 | print_device_status() 58 | target_temperature_type = 'Normal' 59 | 60 | for i in range(3): 61 | print('===========') 62 | target_temperature = 15 + i / 2 63 | print(f'Changing the set temperature to {target_temperature:.1f} C...') 64 | set_temperature_value_for_type(temperature_type=target_temperature_type, temperature=target_temperature) 65 | time.sleep(1) 66 | get_temperature_value_for_temperature_type(target_temperature_type) 67 | time.sleep(1) 68 | 69 | 70 | if __name__ == '__main__': 71 | main() 72 | print('Done!') 73 | 74 | ''' 75 | EXAMPLE OUTPUT: 76 | STATUS: 77 | Name = panel heater gen. 3 78 | Version = 0x211019 79 | Operation key = 80 | 81 | =========== 82 | Changing the set temperature to 15.0 C... 83 | set_temperature = 15.00 84 | 85 | =========== 86 | Changing the set temperature to 15.5 C... 87 | set_temperature = 15.50 88 | 89 | =========== 90 | Changing the set temperature to 16.0 C... 91 | set_temperature = 16.00 92 | 93 | Done! 94 | 95 | Process finished with exit code 0 96 | ''' 97 | -------------------------------------------------------------------------------- /heaters/examples/python/timers.py: -------------------------------------------------------------------------------- 1 | """ 2 | This examples sets a few timers scheduled for the next few minutes, 3 | and queries the status to confirm the proper behaviour. 4 | 5 | Note that the script doesn't need to keep running to have the timers working - 6 | they are stored and executed inside the device. 7 | """ 8 | 9 | import sys 10 | import time 11 | import datetime 12 | 13 | try: 14 | import requests 15 | except ImportError: 16 | print("ERROR! Please install requests library! Run `pip3 install requests` and retry!", file=sys.stderr) 17 | sys.exit(-1) 18 | 19 | 20 | HEATER_ADDRESS = "10.11.12.145" # Please specify IP address of your device here 21 | 22 | 23 | def get_control_status_and_print_it(): 24 | response = requests.get(url=f'http://{HEATER_ADDRESS}/control-status') 25 | if response.status_code != 200: 26 | raise Exception(f"Request error! Body={response.text}") 27 | 28 | control_status = response.json() 29 | 30 | ambient_temperature = control_status['ambient_temperature'] 31 | set_temperature = control_status['set_temperature'] 32 | control_signal = control_status['control_signal'] 33 | 34 | print(f"STATUS:\n" 35 | f" Ambient temperature = {ambient_temperature:.2f}\n" 36 | f" Set temperature = {set_temperature:.1f}\n" 37 | f" Control signal = {control_signal} %\n") 38 | 39 | 40 | def set_timezone_offset(timezone_offset): 41 | payload = {'timezone_offset': timezone_offset} 42 | response = requests.post(url=f'http://{HEATER_ADDRESS}/timezone-offset', json=payload, timeout=5) 43 | if response.status_code != 200: 44 | raise Exception(f"Request error! Body={response.text}") 45 | 46 | 47 | def set_operation_mode(operation_mode): 48 | payload = {'mode': operation_mode} 49 | response = requests.post(url=f'http://{HEATER_ADDRESS}/operation-mode', json=payload, timeout=5) 50 | if response.status_code != 200: 51 | raise Exception(f"Request error! Body={response.text}") 52 | 53 | 54 | def set_temperature_value_for_type(temperature_type, temperature): 55 | payload = {'type': temperature_type, 'value': temperature} 56 | response = requests.post(url=f'http://{HEATER_ADDRESS}/set-temperature', json=payload, timeout=5) 57 | if response.status_code != 200: 58 | raise Exception(f"Request error! Body={response.text}") 59 | 60 | 61 | def set_non_repeatable_timers(timers): 62 | payload = {'non_repeatable_timers': timers} 63 | response = requests.post(url=f'http://{HEATER_ADDRESS}/non-repeatable-timers', json=payload, timeout=5) 64 | if response.status_code != 200: 65 | raise Exception(f"Request error! Body={response.text}") 66 | 67 | 68 | def change_temperature_in_independent_mode_now(value): 69 | payload = {'temperature': value} 70 | response = requests.post(url=f'http://{HEATER_ADDRESS}/set-temperature-in-independent-mode-now', json=payload, timeout=5) 71 | if response.status_code != 200: 72 | raise Exception(f"Request error! Body={response.text}") 73 | 74 | 75 | def get_non_repeatable_timers(): 76 | response = requests.get(url=f'http://{HEATER_ADDRESS}/non-repeatable-timers', timeout=5) 77 | if response.status_code != 200: 78 | raise Exception(f"Request error! Body={response.text}") 79 | 80 | weekly_program = response.json() 81 | print(weekly_program) 82 | 83 | 84 | def main(): 85 | timezone_offset = 60 86 | unix_local_timestamp_in_minutes = int(time.time() / 60) + timezone_offset 87 | target_temperature = 30 88 | 89 | target_timers = [ 90 | {'value_type': 'Normal', 'time': unix_local_timestamp_in_minutes + 1}, 91 | {'value_type': 'Off', 'time': unix_local_timestamp_in_minutes + 2}, 92 | {'value_type': 'Normal', 'time': unix_local_timestamp_in_minutes + 3}, 93 | {'value_type': 'Off', 'time': unix_local_timestamp_in_minutes + 4} 94 | ] 95 | 96 | set_timezone_offset(timezone_offset=timezone_offset) 97 | set_operation_mode(operation_mode='Independent device') 98 | set_temperature_value_for_type(temperature_type='Normal', temperature=target_temperature) 99 | change_temperature_in_independent_mode_now(target_temperature) 100 | set_non_repeatable_timers(timers=target_timers) 101 | 102 | while True: 103 | now = datetime.datetime.now() 104 | print(f'{now.hour}:{now.minute:02d}:{now.second:02d}') 105 | get_control_status_and_print_it() 106 | time.sleep(20) 107 | 108 | 109 | if __name__ == '__main__': 110 | main() 111 | print('Done!') 112 | 113 | ''' 114 | EXAMPLE OUTPUT: 115 | 10:12:57 116 | STATUS: 117 | Ambient temperature = 19.37 118 | Set temperature = 30.0 119 | Control signal = 100 % 120 | 121 | 10:13:17 122 | STATUS: 123 | Ambient temperature = 19.37 124 | Set temperature = 30.0 125 | Control signal = 100 % 126 | 127 | 10:13:37 128 | STATUS: 129 | Ambient temperature = 19.37 130 | Set temperature = 30.0 131 | Control signal = 100 % 132 | 133 | 10:13:57 134 | STATUS: 135 | Ambient temperature = 19.37 136 | Set temperature = 30.0 137 | Control signal = 100 % 138 | 139 | 10:14:17 140 | STATUS: 141 | Ambient temperature = 19.37 142 | Set temperature = 0.0 143 | Control signal = 0 % 144 | 145 | 10:14:37 146 | STATUS: 147 | Ambient temperature = 19.37 148 | Set temperature = 0.0 149 | Control signal = 0 % 150 | 151 | 10:14:58 152 | STATUS: 153 | Ambient temperature = 19.37 154 | Set temperature = 0.0 155 | Control signal = 0 % 156 | 157 | 10:15:18 158 | STATUS: 159 | Ambient temperature = 19.37 160 | Set temperature = 30.0 161 | Control signal = 100 % 162 | 163 | 10:15:38 164 | STATUS: 165 | Ambient temperature = 19.37 166 | Set temperature = 30.0 167 | Control signal = 100 % 168 | 169 | 170 | 171 | ... 172 | ''' 173 | -------------------------------------------------------------------------------- /postman_collection_heaters_gen_3.json: -------------------------------------------------------------------------------- 1 | { 2 | "info": { 3 | "_postman_id": "1629a453-5e2a-43ef-9b13-78ad94728172", 4 | "name": "Mill local API", 5 | "description": "All requests from panel heater local API ", 6 | "schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json" 7 | }, 8 | "item": [ 9 | { 10 | "name": "status", 11 | "protocolProfileBehavior": { 12 | "disableBodyPruning": true 13 | }, 14 | "request": { 15 | "method": "GET", 16 | "header": [], 17 | "body": { 18 | "mode": "raw", 19 | "raw": "", 20 | "options": { 21 | "raw": { 22 | "language": "json" 23 | } 24 | } 25 | }, 26 | "url": { 27 | "raw": "{{heater_addres}}/status", 28 | "host": [ 29 | "{{heater_addres}}" 30 | ], 31 | "path": [ 32 | "status" 33 | ] 34 | } 35 | }, 36 | "response": [] 37 | }, 38 | { 39 | "name": "temperature calibration", 40 | "protocolProfileBehavior": { 41 | "disableBodyPruning": true 42 | }, 43 | "request": { 44 | "method": "GET", 45 | "header": [], 46 | "body": { 47 | "mode": "raw", 48 | "raw": "", 49 | "options": { 50 | "raw": { 51 | "language": "json" 52 | } 53 | } 54 | }, 55 | "url": { 56 | "raw": "{{heater_addres}}/temperature-calibration-offset", 57 | "host": [ 58 | "{{heater_addres}}" 59 | ], 60 | "path": [ 61 | "temperature-calibration-offset" 62 | ] 63 | } 64 | }, 65 | "response": [] 66 | }, 67 | { 68 | "name": "temperature calibration", 69 | "request": { 70 | "method": "POST", 71 | "header": [], 72 | "body": { 73 | "mode": "raw", 74 | "raw": "{\"value\": 20}", 75 | "options": { 76 | "raw": { 77 | "language": "json" 78 | } 79 | } 80 | }, 81 | "url": { 82 | "raw": "{{heater_addres}}/temperature-calibration-offset", 83 | "host": [ 84 | "{{heater_addres}}" 85 | ], 86 | "path": [ 87 | "temperature-calibration-offset" 88 | ] 89 | } 90 | }, 91 | "response": [] 92 | }, 93 | { 94 | "name": "soft reset", 95 | "request": { 96 | "method": "POST", 97 | "header": [], 98 | "url": { 99 | "raw": "{{heater_addres}}/soft-reset", 100 | "host": [ 101 | "{{heater_addres}}" 102 | ], 103 | "path": [ 104 | "soft-reset" 105 | ] 106 | } 107 | }, 108 | "response": [] 109 | }, 110 | { 111 | "name": "hard reset", 112 | "request": { 113 | "method": "POST", 114 | "header": [], 115 | "url": { 116 | "raw": "{{heater_addres}}/hard-reset", 117 | "host": [ 118 | "{{heater_addres}}" 119 | ], 120 | "path": [ 121 | "hard-reset" 122 | ] 123 | } 124 | }, 125 | "response": [] 126 | }, 127 | { 128 | "name": "control status", 129 | "request": { 130 | "method": "GET", 131 | "header": [], 132 | "url": { 133 | "raw": "{{heater_addres}}/control-status", 134 | "host": [ 135 | "{{heater_addres}}" 136 | ], 137 | "path": [ 138 | "control-status" 139 | ] 140 | } 141 | }, 142 | "response": [] 143 | }, 144 | { 145 | "name": "commercial lock", 146 | "request": { 147 | "method": "GET", 148 | "header": [], 149 | "url": { 150 | "raw": "{{heater_addres}}/commercial-lock", 151 | "host": [ 152 | "{{heater_addres}}" 153 | ], 154 | "path": [ 155 | "commercial-lock" 156 | ] 157 | } 158 | }, 159 | "response": [] 160 | }, 161 | { 162 | "name": "commercial lock", 163 | "request": { 164 | "method": "POST", 165 | "header": [], 166 | "body": { 167 | "mode": "raw", 168 | "raw": "{\n \"value\": false\n}", 169 | "options": { 170 | "raw": { 171 | "language": "json" 172 | } 173 | } 174 | }, 175 | "url": { 176 | "raw": "{{heater_addres}}/commercial-lock", 177 | "host": [ 178 | "{{heater_addres}}" 179 | ], 180 | "path": [ 181 | "commercial-lock" 182 | ] 183 | } 184 | }, 185 | "response": [] 186 | }, 187 | { 188 | "name": "commercial lock customization", 189 | "request": { 190 | "method": "GET", 191 | "header": [], 192 | "url": { 193 | "raw": "{{heater_addres}}/commercial-lock-customization", 194 | "host": [ 195 | "{{heater_addres}}" 196 | ], 197 | "path": [ 198 | "commercial-lock-customization" 199 | ] 200 | } 201 | }, 202 | "response": [] 203 | }, 204 | { 205 | "name": "commercial lock customization", 206 | "request": { 207 | "method": "POST", 208 | "header": [], 209 | "body": { 210 | "mode": "raw", 211 | "raw": "{\n \"enabled\": false,\n \"min_allowed_temp_in_commercial_lock\": 11.5,\n \"max_allowed_temp_in_commercial_lock\": 30\n}", 212 | "options": { 213 | "raw": { 214 | "language": "json" 215 | } 216 | } 217 | }, 218 | "url": { 219 | "raw": "{{heater_addres}}/commercial-lock-customization", 220 | "host": [ 221 | "{{heater_addres}}" 222 | ], 223 | "path": [ 224 | "commercial-lock-customization" 225 | ] 226 | } 227 | }, 228 | "response": [] 229 | }, 230 | { 231 | "name": "child lock", 232 | "request": { 233 | "method": "GET", 234 | "header": [], 235 | "url": { 236 | "raw": "{{heater_addres}}/child-lock", 237 | "host": [ 238 | "{{heater_addres}}" 239 | ], 240 | "path": [ 241 | "child-lock" 242 | ] 243 | } 244 | }, 245 | "response": [] 246 | }, 247 | { 248 | "name": "child lock", 249 | "request": { 250 | "method": "POST", 251 | "header": [], 252 | "body": { 253 | "mode": "raw", 254 | "raw": "{\"value\": false}", 255 | "options": { 256 | "raw": { 257 | "language": "json" 258 | } 259 | } 260 | }, 261 | "url": { 262 | "raw": "{{heater_addres}}/child-lock", 263 | "host": [ 264 | "{{heater_addres}}" 265 | ], 266 | "path": [ 267 | "child-lock" 268 | ] 269 | } 270 | }, 271 | "response": [] 272 | }, 273 | { 274 | "name": "open window", 275 | "request": { 276 | "method": "GET", 277 | "header": [], 278 | "url": { 279 | "raw": "{{heater_addres}}/open-window", 280 | "host": [ 281 | "{{heater_addres}}" 282 | ], 283 | "path": [ 284 | "open-window" 285 | ] 286 | } 287 | }, 288 | "response": [] 289 | }, 290 | { 291 | "name": "open window", 292 | "request": { 293 | "method": "POST", 294 | "header": [], 295 | "body": { 296 | "mode": "raw", 297 | "raw": "{\n \"drop_temperature_threshold\": 5,\n \"drop_time_range\": 900,\n \"enabled\": true,\n \"increase_temperature_threshold\": 3,\n \"increase_time_range\": 900,\n \"max_time\": 3600\n}", 298 | "options": { 299 | "raw": { 300 | "language": "json" 301 | } 302 | } 303 | }, 304 | "url": { 305 | "raw": "{{heater_addres}}/open-window", 306 | "host": [ 307 | "{{heater_addres}}" 308 | ], 309 | "path": [ 310 | "open-window" 311 | ] 312 | } 313 | }, 314 | "response": [] 315 | }, 316 | { 317 | "name": "weekly program", 318 | "request": { 319 | "method": "GET", 320 | "header": [], 321 | "url": { 322 | "raw": "{{heater_addres}}/weekly-program", 323 | "host": [ 324 | "{{heater_addres}}" 325 | ], 326 | "path": [ 327 | "weekly-program" 328 | ] 329 | } 330 | }, 331 | "response": [] 332 | }, 333 | { 334 | "name": "weekly program", 335 | "request": { 336 | "method": "POST", 337 | "header": [], 338 | "body": { 339 | "mode": "raw", 340 | "raw": "{\n\"timers\": [\n{\"name\": \"Comfort\", \"timestamp\": 12},\n{\"name\": \"Away\", \"timestamp\": 30},\n{\"name\": \"Sleep\", \"timestamp\": 50}\n]\n}", 341 | "options": { 342 | "raw": { 343 | "language": "json" 344 | } 345 | } 346 | }, 347 | "url": { 348 | "raw": "{{heater_addres}}/weekly-program", 349 | "host": [ 350 | "{{heater_addres}}" 351 | ], 352 | "path": [ 353 | "weekly-program" 354 | ] 355 | } 356 | }, 357 | "response": [] 358 | }, 359 | { 360 | "name": "non repeatable timers", 361 | "request": { 362 | "method": "GET", 363 | "header": [], 364 | "url": { 365 | "raw": "{{heater_addres}}/non-repeatable-timers", 366 | "host": [ 367 | "{{heater_addres}}" 368 | ], 369 | "path": [ 370 | "non-repeatable-timers" 371 | ] 372 | } 373 | }, 374 | "response": [] 375 | }, 376 | { 377 | "name": "non repeatable timers", 378 | "request": { 379 | "method": "POST", 380 | "header": [], 381 | "body": { 382 | "mode": "raw", 383 | "raw": "{\n\"non_repeatable_timers\": [\n{\"name\": \"Comfort\", \"timestamp\": 12},\n{\"name\": \"Away\", \"timestamp\": 30},\n{\"name\": \"Sleep\", \"timestamp\": 50}\n]\n}", 384 | "options": { 385 | "raw": { 386 | "language": "json" 387 | } 388 | } 389 | }, 390 | "url": { 391 | "raw": "{{heater_addres}}/non-repeatable-timers", 392 | "host": [ 393 | "{{heater_addres}}" 394 | ], 395 | "path": [ 396 | "non-repeatable-timers" 397 | ] 398 | } 399 | }, 400 | "response": [] 401 | }, 402 | { 403 | "name": "operation mode", 404 | "request": { 405 | "method": "GET", 406 | "header": [], 407 | "url": { 408 | "raw": "{{heater_addres}}/operation-mode", 409 | "host": [ 410 | "{{heater_addres}}" 411 | ], 412 | "path": [ 413 | "operation-mode" 414 | ] 415 | } 416 | }, 417 | "response": [] 418 | }, 419 | { 420 | "name": "operation mode", 421 | "request": { 422 | "method": "POST", 423 | "header": [], 424 | "body": { 425 | "mode": "raw", 426 | "raw": "{\n \"mode\": \"Independent device\"\n}", 427 | "options": { 428 | "raw": { 429 | "language": "json" 430 | } 431 | } 432 | }, 433 | "url": { 434 | "raw": "{{heater_addres}}/operation-mode", 435 | "host": [ 436 | "{{heater_addres}}" 437 | ], 438 | "path": [ 439 | "operation-mode" 440 | ] 441 | } 442 | }, 443 | "response": [] 444 | }, 445 | { 446 | "name": "display unit", 447 | "request": { 448 | "method": "GET", 449 | "header": [], 450 | "url": { 451 | "raw": "{{heater_addres}}/display-unit", 452 | "host": [ 453 | "{{heater_addres}}" 454 | ], 455 | "path": [ 456 | "display-unit" 457 | ] 458 | } 459 | }, 460 | "response": [] 461 | }, 462 | { 463 | "name": "display unit", 464 | "request": { 465 | "method": "POST", 466 | "header": [], 467 | "body": { 468 | "mode": "raw", 469 | "raw": "{\n \"value\": \"Farenheit\"\n}", 470 | "options": { 471 | "raw": { 472 | "language": "json" 473 | } 474 | } 475 | }, 476 | "url": { 477 | "raw": "{{heater_addres}}/display-unit", 478 | "host": [ 479 | "{{heater_addres}}" 480 | ], 481 | "path": [ 482 | "display-unit" 483 | ] 484 | } 485 | }, 486 | "response": [] 487 | }, 488 | { 489 | "name": "set temperature", 490 | "protocolProfileBehavior": { 491 | "disableBodyPruning": true 492 | }, 493 | "request": { 494 | "method": "GET", 495 | "header": [], 496 | "body": { 497 | "mode": "raw", 498 | "raw": "{\n \"type\": \"Away\"\n}", 499 | "options": { 500 | "raw": { 501 | "language": "json" 502 | } 503 | } 504 | }, 505 | "url": { 506 | "raw": "{{heater_addres}}/set-temperature", 507 | "host": [ 508 | "{{heater_addres}}" 509 | ], 510 | "path": [ 511 | "set-temperature" 512 | ] 513 | } 514 | }, 515 | "response": [] 516 | }, 517 | { 518 | "name": "set temperature", 519 | "request": { 520 | "method": "POST", 521 | "header": [], 522 | "body": { 523 | "mode": "raw", 524 | "raw": "{\n \"type\": \"Normal\",\n \"value\": 30\n}", 525 | "options": { 526 | "raw": { 527 | "language": "json" 528 | } 529 | } 530 | }, 531 | "url": { 532 | "raw": "{{heater_addres}}/set-temperature", 533 | "host": [ 534 | "{{heater_addres}}" 535 | ], 536 | "path": [ 537 | "set-temperature" 538 | ] 539 | } 540 | }, 541 | "response": [] 542 | }, 543 | { 544 | "name": "pid parameters", 545 | "request": { 546 | "method": "GET", 547 | "header": [], 548 | "url": { 549 | "raw": "{{heater_addres}}/pid-parameters", 550 | "host": [ 551 | "{{heater_addres}}" 552 | ], 553 | "path": [ 554 | "pid-parameters" 555 | ] 556 | } 557 | }, 558 | "response": [] 559 | }, 560 | { 561 | "name": "pid parameters", 562 | "request": { 563 | "method": "POST", 564 | "header": [], 565 | "body": { 566 | "mode": "raw", 567 | "raw": "{\n \"kp\": 70,\n \"ki\": 0.04,\n \"kd\": 9000,\n \"kd_filter_N\": 60,\n \"windup_limit_percentage\": 90\n}", 568 | "options": { 569 | "raw": { 570 | "language": "json" 571 | } 572 | } 573 | }, 574 | "url": { 575 | "raw": "{{heater_addres}}/pid-parameters", 576 | "host": [ 577 | "{{heater_addres}}" 578 | ], 579 | "path": [ 580 | "pid-parameters" 581 | ] 582 | } 583 | }, 584 | "response": [] 585 | }, 586 | { 587 | "name": "cloud communication", 588 | "request": { 589 | "method": "GET", 590 | "header": [], 591 | "url": { 592 | "raw": "{{heater_addres}}/cloud-communication", 593 | "host": [ 594 | "{{heater_addres}}" 595 | ], 596 | "path": [ 597 | "cloud-communication" 598 | ] 599 | } 600 | }, 601 | "response": [] 602 | }, 603 | { 604 | "name": "cloud communication", 605 | "request": { 606 | "method": "POST", 607 | "header": [], 608 | "body": { 609 | "mode": "raw", 610 | "raw": "{\n \"value\": true\n}", 611 | "options": { 612 | "raw": { 613 | "language": "json" 614 | } 615 | } 616 | }, 617 | "url": { 618 | "raw": "{{heater_addres}}/cloud-communication", 619 | "host": [ 620 | "{{heater_addres}}" 621 | ], 622 | "path": [ 623 | "cloud-communication" 624 | ] 625 | } 626 | }, 627 | "response": [] 628 | }, 629 | { 630 | "name": "ota update ", 631 | "request": { 632 | "method": "POST", 633 | "header": [], 634 | "body": { 635 | "mode": "raw", 636 | "raw": "{\n \"address\": \"fff\"\n}", 637 | "options": { 638 | "raw": { 639 | "language": "json" 640 | } 641 | } 642 | }, 643 | "url": { 644 | "raw": "{{heater_addres}}/ota-update", 645 | "host": [ 646 | "{{heater_addres}}" 647 | ], 648 | "path": [ 649 | "ota-update" 650 | ] 651 | } 652 | }, 653 | "response": [] 654 | }, 655 | { 656 | "name": "config parameter", 657 | "protocolProfileBehavior": { 658 | "disableBodyPruning": true 659 | }, 660 | "request": { 661 | "method": "GET", 662 | "header": [], 663 | "body": { 664 | "mode": "raw", 665 | "raw": "{\n \"name\": \"set\"\n}", 666 | "options": { 667 | "raw": { 668 | "language": "json" 669 | } 670 | } 671 | }, 672 | "url": { 673 | "raw": "{{heater_addres}}/config-parameter", 674 | "host": [ 675 | "{{heater_addres}}" 676 | ], 677 | "path": [ 678 | "config-parameter" 679 | ] 680 | } 681 | }, 682 | "response": [] 683 | }, 684 | { 685 | "name": "config parameter", 686 | "request": { 687 | "method": "POST", 688 | "header": [], 689 | "body": { 690 | "mode": "raw", 691 | "raw": "{\n \"name\": \"set\",\n \"value\": \"70\"\n}", 692 | "options": { 693 | "raw": { 694 | "language": "json" 695 | } 696 | } 697 | }, 698 | "url": { 699 | "raw": "{{heater_addres}}/config-parameter", 700 | "host": [ 701 | "{{heater_addres}}" 702 | ], 703 | "path": [ 704 | "config-parameter" 705 | ] 706 | } 707 | }, 708 | "response": [] 709 | }, 710 | { 711 | "name": "ablecloud message", 712 | "request": { 713 | "method": "POST", 714 | "header": [], 715 | "body": { 716 | "mode": "raw", 717 | "raw": "{\n \"message_code\": 3,\n \"data\": \"4443\"\n}", 718 | "options": { 719 | "raw": { 720 | "language": "json" 721 | } 722 | } 723 | }, 724 | "url": { 725 | "raw": "{{heater_addres}}/ablecloud-message", 726 | "host": [ 727 | "{{heater_addres}}" 728 | ], 729 | "path": [ 730 | "ablecloud-message" 731 | ] 732 | } 733 | }, 734 | "response": [] 735 | }, 736 | { 737 | "name": "scan wifi", 738 | "request": { 739 | "method": "GET", 740 | "header": [], 741 | "url": { 742 | "raw": "{{heater_addres}}/scan-wifi", 743 | "host": [ 744 | "{{heater_addres}}" 745 | ], 746 | "path": [ 747 | "scan-wifi" 748 | ] 749 | } 750 | }, 751 | "response": [] 752 | }, 753 | { 754 | "name": "device config", 755 | "request": { 756 | "method": "POST", 757 | "header": [], 758 | "body": { 759 | "mode": "raw", 760 | "raw": "{\n \"ssid\": \"ss\",\n \"password\": \"dda\",\n \"connectivity_option\": \"sta_cloud_and_local_api\"\n}", 761 | "options": { 762 | "raw": { 763 | "language": "json" 764 | } 765 | } 766 | }, 767 | "url": { 768 | "raw": "{{heater_addres}}/device-config", 769 | "host": [ 770 | "{{heater_addres}}" 771 | ], 772 | "path": [ 773 | "device-config" 774 | ] 775 | } 776 | }, 777 | "response": [] 778 | }, 779 | { 780 | "name": "reboot", 781 | "request": { 782 | "method": "POST", 783 | "header": [], 784 | "url": { 785 | "raw": "{{heater_addres}}/reboot", 786 | "host": [ 787 | "{{heater_addres}}" 788 | ], 789 | "path": [ 790 | "reboot" 791 | ] 792 | } 793 | }, 794 | "response": [] 795 | }, 796 | { 797 | "name": "predicitive heating type", 798 | "request": { 799 | "method": "GET", 800 | "header": [], 801 | "url": { 802 | "raw": "{{heater_addres}}/predictive-heating-type", 803 | "host": [ 804 | "{{heater_addres}}" 805 | ], 806 | "path": [ 807 | "predictive-heating-type" 808 | ] 809 | } 810 | }, 811 | "response": [] 812 | }, 813 | { 814 | "name": "predicitive heating type", 815 | "request": { 816 | "method": "POST", 817 | "header": [], 818 | "body": { 819 | "mode": "raw", 820 | "raw": "{\n \"predictive_heating_type\": \"Simple\"\n}", 821 | "options": { 822 | "raw": { 823 | "language": "json" 824 | } 825 | } 826 | }, 827 | "url": { 828 | "raw": "{{heater_addres}}/predictive-heating-type", 829 | "host": [ 830 | "{{heater_addres}}" 831 | ], 832 | "path": [ 833 | "predictive-heating-type" 834 | ] 835 | } 836 | }, 837 | "response": [] 838 | }, 839 | { 840 | "name": "overwrite weekly program ", 841 | "request": { 842 | "method": "POST", 843 | "header": [], 844 | "body": { 845 | "mode": "raw", 846 | "raw": "{\n \"duration\": 1,\n \"type\": \"Away\"\n}", 847 | "options": { 848 | "raw": { 849 | "language": "json" 850 | } 851 | } 852 | }, 853 | "url": { 854 | "raw": "{{heater_addres}}/overwrite-weekly-program", 855 | "host": [ 856 | "{{heater_addres}}" 857 | ], 858 | "path": [ 859 | "overwrite-weekly-program" 860 | ] 861 | } 862 | }, 863 | "response": [] 864 | }, 865 | { 866 | "name": "oil heater power", 867 | "protocolProfileBehavior": { 868 | "disableBodyPruning": true 869 | }, 870 | "request": { 871 | "method": "GET", 872 | "header": [], 873 | "body": { 874 | "mode": "raw", 875 | "raw": "", 876 | "options": { 877 | "raw": { 878 | "language": "json" 879 | } 880 | } 881 | }, 882 | "url": { 883 | "raw": "{{heater_addres}}/oil-heater-power", 884 | "host": [ 885 | "{{heater_addres}}" 886 | ], 887 | "path": [ 888 | "oil-heater-power" 889 | ] 890 | } 891 | }, 892 | "response": [] 893 | }, 894 | { 895 | "name": "max heater power", 896 | "request": { 897 | "method": "POST", 898 | "header": [], 899 | "body": { 900 | "mode": "raw", 901 | "raw": "{\n \"power\": 1,\n \"calibrate\": true\n}", 902 | "options": { 903 | "raw": { 904 | "language": "json" 905 | } 906 | } 907 | }, 908 | "url": { 909 | "raw": "{{heater_addres}}/max-heater-power", 910 | "host": [ 911 | "{{heater_addres}}" 912 | ], 913 | "path": [ 914 | "max-heater-power" 915 | ] 916 | } 917 | }, 918 | "response": [] 919 | }, 920 | { 921 | "name": "oil heater power", 922 | "request": { 923 | "method": "POST", 924 | "header": [], 925 | "body": { 926 | "mode": "raw", 927 | "raw": "{\n \"heating_level_percentage\": 100\n}", 928 | "options": { 929 | "raw": { 930 | "language": "json" 931 | } 932 | } 933 | }, 934 | "url": { 935 | "raw": "{{heater_addres}}/oil-heater-power", 936 | "host": [ 937 | "{{heater_addres}}" 938 | ], 939 | "path": [ 940 | "oil-heater-power" 941 | ] 942 | } 943 | }, 944 | "response": [] 945 | }, 946 | { 947 | "name": "vacation mode", 948 | "request": { 949 | "method": "POST", 950 | "header": [], 951 | "body": { 952 | "mode": "raw", 953 | "raw": "{\n \"start_timestamp\": 0,\n \"end_timestamp\": 0\n}", 954 | "options": { 955 | "raw": { 956 | "language": "json" 957 | } 958 | } 959 | }, 960 | "url": { 961 | "raw": "{{heater_addres}}/vacation-mode", 962 | "host": [ 963 | "{{heater_addres}}" 964 | ], 965 | "path": [ 966 | "vacation-mode" 967 | ] 968 | } 969 | }, 970 | "response": [] 971 | }, 972 | { 973 | "name": "vacation mode", 974 | "request": { 975 | "method": "GET", 976 | "header": [], 977 | "url": { 978 | "raw": "{{heater_addres}}/vacation-mode", 979 | "host": [ 980 | "{{heater_addres}}" 981 | ], 982 | "path": [ 983 | "vacation-mode" 984 | ] 985 | } 986 | }, 987 | "response": [] 988 | }, 989 | { 990 | "name": "timezone offset", 991 | "request": { 992 | "method": "GET", 993 | "header": [], 994 | "url": { 995 | "raw": "{{heater_addres}}/timezone-offset", 996 | "host": [ 997 | "{{heater_addres}}" 998 | ], 999 | "path": [ 1000 | "timezone-offset" 1001 | ] 1002 | } 1003 | }, 1004 | "response": [] 1005 | }, 1006 | { 1007 | "name": "timezone offset", 1008 | "request": { 1009 | "method": "POST", 1010 | "header": [], 1011 | "body": { 1012 | "mode": "raw", 1013 | "raw": "{\n \"timezone_offset\": 0\n}", 1014 | "options": { 1015 | "raw": { 1016 | "language": "json" 1017 | } 1018 | } 1019 | }, 1020 | "url": { 1021 | "raw": "{{heater_addres}}/timezone-offset", 1022 | "host": [ 1023 | "{{heater_addres}}" 1024 | ], 1025 | "path": [ 1026 | "timezone-offset" 1027 | ] 1028 | } 1029 | }, 1030 | "response": [] 1031 | }, 1032 | { 1033 | "name": "set temperature in independent mode now", 1034 | "request": { 1035 | "method": "POST", 1036 | "header": [], 1037 | "body": { 1038 | "mode": "raw", 1039 | "raw": "{\n \"temperature\": 0\n}", 1040 | "options": { 1041 | "raw": { 1042 | "language": "json" 1043 | } 1044 | } 1045 | }, 1046 | "url": { 1047 | "raw": "{{heater_addres}}/set-temperature-in-independent-mode-now", 1048 | "host": [ 1049 | "{{heater_addres}}" 1050 | ], 1051 | "path": [ 1052 | "set-temperature-in-independent-mode-now" 1053 | ] 1054 | } 1055 | }, 1056 | "response": [] 1057 | }, 1058 | { 1059 | "name": "additional socket mode", 1060 | "request": { 1061 | "method": "GET", 1062 | "header": [], 1063 | "url": { 1064 | "raw": "{{heater_addres}}/additional-socket-mode", 1065 | "host": [ 1066 | "{{heater_addres}}" 1067 | ], 1068 | "path": [ 1069 | "additional-socket-mode" 1070 | ] 1071 | } 1072 | }, 1073 | "response": [] 1074 | }, 1075 | { 1076 | "name": "additional socket mode", 1077 | "request": { 1078 | "method": "POST", 1079 | "header": [], 1080 | "body": { 1081 | "mode": "raw", 1082 | "raw": "{\n \"additional_mode\": 0\n}", 1083 | "options": { 1084 | "raw": { 1085 | "language": "json" 1086 | } 1087 | } 1088 | }, 1089 | "url": { 1090 | "raw": "{{heater_addres}}/additional-socket-mode", 1091 | "host": [ 1092 | "{{heater_addres}}" 1093 | ], 1094 | "path": [ 1095 | "additional-socket-mode" 1096 | ] 1097 | } 1098 | }, 1099 | "response": [] 1100 | }, 1101 | { 1102 | "name": "hysteresis parameters", 1103 | "request": { 1104 | "method": "GET", 1105 | "header": [], 1106 | "url": { 1107 | "raw": "{{heater_addres}}/hysteresis-parameters", 1108 | "host": [ 1109 | "{{heater_addres}}" 1110 | ], 1111 | "path": [ 1112 | "hysteresis-parameters" 1113 | ] 1114 | } 1115 | }, 1116 | "response": [] 1117 | }, 1118 | { 1119 | "name": "hysteresis parameters", 1120 | "request": { 1121 | "method": "POST", 1122 | "header": [], 1123 | "body": { 1124 | "mode": "raw", 1125 | "raw": "{\n \"temp_hysteresis_upper\": 1,\n \"temp_hysteresis_lower\": 1\n}", 1126 | "options": { 1127 | "raw": { 1128 | "language": "json" 1129 | } 1130 | } 1131 | }, 1132 | "url": { 1133 | "raw": "{{heater_addres}}/hysteresis-parameters", 1134 | "host": [ 1135 | "{{heater_addres}}" 1136 | ], 1137 | "path": [ 1138 | "hysteresis-parameters" 1139 | ] 1140 | } 1141 | }, 1142 | "response": [] 1143 | }, 1144 | { 1145 | "name": "limited heating power", 1146 | "request": { 1147 | "method": "GET", 1148 | "header": [], 1149 | "url": { 1150 | "raw": "{{heater_addres}}/limited-heating-power", 1151 | "host": [ 1152 | "{{heater_addres}}" 1153 | ], 1154 | "path": [ 1155 | "limited-heating-power" 1156 | ] 1157 | } 1158 | }, 1159 | "response": [] 1160 | }, 1161 | { 1162 | "name": "limited heating power", 1163 | "request": { 1164 | "method": "POST", 1165 | "header": [], 1166 | "body": { 1167 | "mode": "raw", 1168 | "raw": "{\n \"limited_heating_power\": 75\n}", 1169 | "options": { 1170 | "raw": { 1171 | "language": "json" 1172 | } 1173 | } 1174 | }, 1175 | "url": { 1176 | "raw": "{{heater_addres}}/limited-heating-power", 1177 | "host": [ 1178 | "{{heater_addres}}" 1179 | ], 1180 | "path": [ 1181 | "limited-heating-power" 1182 | ] 1183 | } 1184 | }, 1185 | "response": [] 1186 | }, 1187 | { 1188 | "name": "controller type", 1189 | "request": { 1190 | "method": "GET", 1191 | "header": [], 1192 | "url": { 1193 | "raw": "{{heater_addres}}/controller-type", 1194 | "host": [ 1195 | "{{heater_addres}}" 1196 | ], 1197 | "path": [ 1198 | "controller-type" 1199 | ] 1200 | } 1201 | }, 1202 | "response": [] 1203 | }, 1204 | { 1205 | "name": "controller type", 1206 | "request": { 1207 | "method": "POST", 1208 | "header": [], 1209 | "body": { 1210 | "mode": "raw", 1211 | "raw": "{\n \"regulator_type\": \"unknown\"\n}", 1212 | "options": { 1213 | "raw": { 1214 | "language": "json" 1215 | } 1216 | } 1217 | }, 1218 | "url": { 1219 | "raw": "{{heater_addres}}/controller-type", 1220 | "host": [ 1221 | "{{heater_addres}}" 1222 | ], 1223 | "path": [ 1224 | "controller-type" 1225 | ] 1226 | } 1227 | }, 1228 | "response": [] 1229 | }, 1230 | { 1231 | "name": "set custom name", 1232 | "request": { 1233 | "method": "POST", 1234 | "header": [], 1235 | "body": { 1236 | "mode": "raw", 1237 | "raw": "{\n \"device_name\": \"123456789012345678901234567890\"\n}", 1238 | "options": { 1239 | "raw": { 1240 | "language": "json" 1241 | } 1242 | } 1243 | }, 1244 | "url": { 1245 | "raw": "{{heater_addres}}/set-custom-name", 1246 | "host": [ 1247 | "{{heater_addres}}" 1248 | ], 1249 | "path": [ 1250 | "set-custom-name" 1251 | ] 1252 | } 1253 | }, 1254 | "response": [] 1255 | }, 1256 | { 1257 | "name": "decrease set temperature", 1258 | "request": { 1259 | "method": "POST", 1260 | "header": [], 1261 | "url": { 1262 | "raw": "{{heater_addres}}/decrease-set-temperature", 1263 | "host": [ 1264 | "{{heater_addres}}" 1265 | ], 1266 | "path": [ 1267 | "decrease-set-temperature" 1268 | ] 1269 | } 1270 | }, 1271 | "response": [] 1272 | }, 1273 | { 1274 | "name": "increase set temperature", 1275 | "request": { 1276 | "method": "POST", 1277 | "header": [], 1278 | "url": { 1279 | "raw": "{{heater_addres}}/increase-set-temperature", 1280 | "host": [ 1281 | "{{heater_addres}}" 1282 | ], 1283 | "path": [ 1284 | "increase-set-temperature" 1285 | ] 1286 | } 1287 | }, 1288 | "response": [] 1289 | }, 1290 | { 1291 | "name": "set api key", 1292 | "request": { 1293 | "method": "POST", 1294 | "header": [], 1295 | "body": { 1296 | "mode": "raw", 1297 | "raw": "{\n \"api_key\": \"adfafsd\"\n}", 1298 | "options": { 1299 | "raw": { 1300 | "language": "json" 1301 | } 1302 | } 1303 | }, 1304 | "url": { 1305 | "raw": "{{heater_addres}}/set-api-key", 1306 | "host": [ 1307 | "{{heater_addres}}" 1308 | ], 1309 | "path": [ 1310 | "set-api-key" 1311 | ] 1312 | } 1313 | } 1314 | } 1315 | ] 1316 | } --------------------------------------------------------------------------------