├── .clang-format
├── .devcontainer
├── Dockerfile
└── devcontainer.json
├── .github
├── version.py
└── workflows
│ ├── Dockerfile-esp32-build
│ ├── Dockerfile-mos
│ ├── build.yaml
│ ├── check-format.yaml
│ ├── howto.build
│ └── stale.yml
├── .gitignore
├── AUTHORS.md
├── LICENSE
├── Makefile
├── README.md
├── docs
└── SDNT1608-0.1-10.png
├── fs
└── favicon.ico.gz
├── fs_src
├── index.html
├── logo.svg
├── qrcode.js
├── script.js
├── sha256.js
└── style.css
├── libreset
├── include
│ └── shelly_reset.hpp
├── mos.yml
└── src
│ └── shelly_reset.cpp
├── mos.yml
├── src
├── ADE7953
│ ├── shelly_pm_ade7953.cpp
│ └── shelly_pm_ade7953.hpp
├── BL0937
│ ├── shelly_pm_bl0937.cpp
│ └── shelly_pm_bl0937.hpp
├── BL0942
│ ├── shelly_pm_bl0942.cpp
│ └── shelly_pm_bl0942.hpp
├── DHT
│ ├── shelly_dht_sensor.cpp
│ └── shelly_dht_sensor.hpp
├── DS18XXX
│ ├── shelly_temp_sensor_ow.cpp
│ └── shelly_temp_sensor_ow.hpp
├── Shelly1
│ └── shelly_init.cpp
├── Shelly1L
│ └── shelly_init.cpp
├── Shelly1PM
│ └── shelly_init.cpp
├── Shelly2
│ └── shelly_init.cpp
├── Shelly25
│ ├── shelly_init_components.cpp
│ └── shelly_init_peripherals.cpp
├── ShellyColorBulb
│ └── shelly_init.cpp
├── ShellyDuo
│ └── shelly_init.cpp
├── ShellyI3
│ └── shelly_init.cpp
├── ShellyMini1Gen3
│ └── shelly_init.cpp
├── ShellyMini1PMGen3
│ └── shelly_init.cpp
├── ShellyPlug
│ └── shelly_init.cpp
├── ShellyPlugS
│ └── shelly_init.cpp
├── ShellyPlus1
│ └── shelly_init.cpp
├── ShellyPlus1PM
│ └── shelly_init.cpp
├── ShellyPlus2PM
│ └── shelly_init.cpp
├── ShellyPlusI4
│ └── shelly_init.cpp
├── ShellyPlusPlugS
│ └── shelly_init.cpp
├── ShellyRGBW2
│ └── shelly_init.cpp
├── ShellyT32
│ └── shelly_init.cpp
├── ShellyU
│ └── shelly_init.cpp
├── ShellyU25
│ └── shelly_init.cpp
├── ShellyUNI
│ └── shelly_init.cpp
├── ShellyVintage
│ └── shelly_init.cpp
├── mock
│ ├── pwm
│ │ ├── mgos_pwm.c
│ │ └── mgos_pwm.h
│ ├── shelly_mock.hpp
│ ├── shelly_mock_pm.cpp
│ ├── shelly_mock_pm.hpp
│ ├── shelly_mock_rpc_service.cpp
│ ├── shelly_mock_temp_sensor.cpp
│ ├── shelly_mock_temp_sensor.hpp
│ └── wifi_config
│ │ └── shelly_wifi_config_impl.cpp
├── noisy_input_pin
│ └── shelly_noisy_input_pin.cpp
├── shelly_cct_controller.cpp
├── shelly_cct_controller.hpp
├── shelly_common.hpp
├── shelly_component.cpp
├── shelly_component.hpp
├── shelly_debug.cpp
├── shelly_debug.hpp
├── shelly_hap_adaptive_lighting.cpp
├── shelly_hap_adaptive_lighting.hpp
├── shelly_hap_carbon_dioxide_sensor.cpp
├── shelly_hap_carbon_dioxide_sensor.hpp
├── shelly_hap_carbon_monoxide_sensor.cpp
├── shelly_hap_carbon_monoxide_sensor.hpp
├── shelly_hap_contact_sensor.cpp
├── shelly_hap_contact_sensor.hpp
├── shelly_hap_doorbell.cpp
├── shelly_hap_doorbell.hpp
├── shelly_hap_garage_door_opener.cpp
├── shelly_hap_garage_door_opener.hpp
├── shelly_hap_humidity_sensor.cpp
├── shelly_hap_humidity_sensor.hpp
├── shelly_hap_input.cpp
├── shelly_hap_input.hpp
├── shelly_hap_leak_sensor.cpp
├── shelly_hap_leak_sensor.hpp
├── shelly_hap_light_bulb.cpp
├── shelly_hap_light_bulb.hpp
├── shelly_hap_lock.cpp
├── shelly_hap_lock.hpp
├── shelly_hap_motion_sensor.cpp
├── shelly_hap_motion_sensor.hpp
├── shelly_hap_occupancy_sensor.cpp
├── shelly_hap_occupancy_sensor.hpp
├── shelly_hap_outlet.cpp
├── shelly_hap_outlet.hpp
├── shelly_hap_sensor_base.cpp
├── shelly_hap_sensor_base.hpp
├── shelly_hap_smoke_sensor.cpp
├── shelly_hap_smoke_sensor.hpp
├── shelly_hap_stateless_switch.cpp
├── shelly_hap_stateless_switch.hpp
├── shelly_hap_stateless_switch_base.cpp
├── shelly_hap_stateless_switch_base.hpp
├── shelly_hap_switch.cpp
├── shelly_hap_switch.hpp
├── shelly_hap_temperature_sensor.cpp
├── shelly_hap_temperature_sensor.hpp
├── shelly_hap_valve.cpp
├── shelly_hap_valve.hpp
├── shelly_hap_window_covering.cpp
├── shelly_hap_window_covering.hpp
├── shelly_input.cpp
├── shelly_input.hpp
├── shelly_input_pin.cpp
├── shelly_input_pin.hpp
├── shelly_light_bulb_controller.cpp
├── shelly_light_bulb_controller.hpp
├── shelly_main.cpp
├── shelly_main.hpp
├── shelly_noisy_input_pin.hpp
├── shelly_ota.cpp
├── shelly_ota.hpp
├── shelly_output.cpp
├── shelly_output.hpp
├── shelly_pm.cpp
├── shelly_pm.hpp
├── shelly_rgbw_controller.cpp
├── shelly_rgbw_controller.hpp
├── shelly_rpc_service.cpp
├── shelly_rpc_service.hpp
├── shelly_statusled.cpp
├── shelly_statusled.hpp
├── shelly_switch.cpp
├── shelly_switch.hpp
├── shelly_sys_led_btn.cpp
├── shelly_sys_led_btn.hpp
├── shelly_temp_sensor.cpp
├── shelly_temp_sensor.hpp
├── shelly_temp_sensor_ntc.cpp
├── shelly_temp_sensor_ntc.hpp
├── shelly_white_controller.cpp
├── shelly_white_controller.hpp
├── shelly_wifi_config.cpp
├── shelly_wifi_config.hpp
└── wifi_config
│ └── shelly_wifi_config_impl.cpp
└── tools
├── flash-shelly.py
└── shelly_update_server
├── .gitignore
├── README.md
├── go.mod
├── go.sum
├── main.go
├── parse_log.go
├── stock_model_map.yml
└── update_handler.go
/.clang-format:
--------------------------------------------------------------------------------
1 | BasedOnStyle: Google
2 | AllowShortFunctionsOnASingleLine: false
3 | SpaceAfterCStyleCast: true
4 | PointerBindsToType: false
5 | DerivePointerBinding: false
6 | IncludeBlocks: Preserve
7 | JavaScriptQuotes: Double
8 |
--------------------------------------------------------------------------------
/.devcontainer/Dockerfile:
--------------------------------------------------------------------------------
1 | # See here for image contents: https://github.com/microsoft/vscode-dev-containers/tree/v0.209.6/containers/ubuntu/.devcontainer/base.Dockerfile
2 |
3 | # [Choice] Ubuntu version (use hirsuite or bionic on local arm64/Apple Silicon): hirsute, focal, bionic
4 | ARG VARIANT="22.04"
5 | FROM mcr.microsoft.com/devcontainers/base:ubuntu-${VARIANT}
6 |
7 | # [Optional] Uncomment this section to install additional OS packages.
8 | RUN apt-get update && export DEBIAN_FRONTEND=noninteractive \
9 | && apt-get -y install --no-install-recommends clang-format make software-properties-common
10 | RUN add-apt-repository ppa:mongoose-os/mos && apt-get update && apt-get -y install mos-latest libavahi-client3 avahi-daemon clang
11 |
--------------------------------------------------------------------------------
/.devcontainer/devcontainer.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "Ubuntu",
3 | "build": {
4 | "dockerfile": "Dockerfile",
5 | "args": {
6 | "VARIANT": "22.04"
7 | }
8 | },
9 | // Set *default* container specific settings.json values on container create.
10 | "customizations": {
11 | "vscode": {
12 | "settings": {
13 | "terminal.integrated.shell.linux": "zsh"
14 | },
15 | // Add the IDs of extensions you want installed when the container is created.
16 | "extensions": [],
17 | "tasks": [
18 | {
19 | "label": "Fileserver",
20 | "type": "shell",
21 | "command": "make build",
22 | "problemMatcher": []
23 | }
24 | ]
25 | }
26 | },
27 | // Use 'forwardPorts' to make a list of ports inside the container available locally.
28 | // "forwardPorts": [],
29 | // Use 'postCreateCommand' to run commands after the container is created.
30 | // "postCreateCommand": "uname -a",
31 | // Comment out connect as root instead. More info: https://aka.ms/vscode-remote/containers/non-root.
32 | "remoteUser": "vscode",
33 | "features": {
34 | "ghcr.io/devcontainers/features/docker-in-docker:2": {},
35 | "git": "latest"
36 | },
37 | "postStartCommand": "sudo service dbus start; sudo service avahi-daemon start"
38 | }
39 |
--------------------------------------------------------------------------------
/.github/version.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/python3
2 | import argparse
3 | import subprocess
4 |
5 | def run(*args):
6 | return subprocess.check_output(args).decode('utf-8').strip()
7 |
8 | def git_describe(*args):
9 | return run('git', 'describe', '--tags', *args)
10 |
11 | def git_branch_name():
12 | return run('git', 'branch', '--show-current')
13 |
14 | def commits_since_forkpoint():
15 | return int(run('git', 'rev-list', '--count', '--no-merges', 'origin/master..'))
16 |
17 | if __name__ == "__main__":
18 | parser = argparse.ArgumentParser(description='Get Shelly-HomeKit version name using Git')
19 | parser.add_argument('-s', '--suffix', action='store_true', help='output only the suffix after the version number')
20 | parser.add_argument('-r', '--release', action='store_true', help='just use tag number, for stable releases')
21 | args, extra_args = parser.parse_known_args()
22 |
23 | # all unknown command line arguments are passed directly to git-describe
24 | tag_name, commits_since_tag, extra = git_describe(*extra_args).split(sep='-', maxsplit=2)
25 |
26 | # usually this is just the sha of the git commit
27 | # however if e.g. --dirty is passed then, if working tree
28 | # dirty, it will be contained in the `info` list
29 | info = extra.split('-')
30 |
31 | version = "" if args.suffix else tag_name
32 |
33 | if args.release:
34 | print(version)
35 | exit()
36 |
37 | branch = git_branch_name()
38 | if branch == "master":
39 | version += f"-latest{commits_since_tag}"
40 | else:
41 | # strip dashes from the branch name so it doesn't mess up update
42 | version += f"-{branch.replace('-', '')}{commits_since_forkpoint()}"
43 |
44 | # append things like -dirty and -broken,
45 | # if passed, to the version name
46 | version += '-'.join(['', *info[1:]])
47 |
48 | print(version)
49 |
--------------------------------------------------------------------------------
/.github/workflows/Dockerfile-esp32-build:
--------------------------------------------------------------------------------
1 | FROM mgos/esp32-build:4.4.1-r7
2 |
3 | RUN chmod o+rx /opt/Espressif
4 |
--------------------------------------------------------------------------------
/.github/workflows/Dockerfile-mos:
--------------------------------------------------------------------------------
1 | FROM ubuntu:22.04
2 |
3 | RUN apt-get update && \
4 | apt-get install -y -q software-properties-common && add-apt-repository -y ppa:mongoose-os/mos && \
5 | apt -q install -y mos-latest docker.io make git && \
6 | apt-get clean && \
7 | rm -rf /var/lib/apt/lists/*
8 |
--------------------------------------------------------------------------------
/.github/workflows/build.yaml:
--------------------------------------------------------------------------------
1 | name: build-shelly-homekit
2 | on:
3 | push:
4 | pull_request:
5 | jobs:
6 | build:
7 | name: Build ${{ matrix.model }}
8 | runs-on: ubuntu-latest
9 | container:
10 | image: ghcr.io/markirb/mos:latest
11 | volumes:
12 | - /home/runner/work:/home/runner/work
13 | strategy:
14 | fail-fast: false
15 | matrix:
16 | model:
17 | - Shelly1
18 | - Shelly1Gen3
19 | - Shelly1L
20 | - Shelly1PM
21 | - Shelly1PMGen3
22 | - Shelly2
23 | - Shelly25
24 | - Shelly2PMGen3
25 | - ShellyColorBulb
26 | - ShellyDuo
27 | - ShellyI3
28 | - ShellyI4Gen3
29 | - ShellyMini1Gen3
30 | - ShellyMini1PMGen3
31 | - ShellyPlug
32 | - ShellyPlugS
33 | - ShellyPlugSGen3
34 | - ShellyPlus1
35 | - ShellyPlus1Mini
36 | - ShellyPlus1PM
37 | - ShellyPlus1PMMini
38 | - ShellyPlus2PM
39 | - ShellyPlusI4
40 | - ShellyPlusPlugS
41 | - ShellyPlusRGBWPM
42 | - ShellyPlusUni
43 | - ShellyRGBW2
44 | - ShellyUNI
45 | - ShellyVintage
46 | steps:
47 | - name: Checkout code
48 | uses: actions/checkout@v4
49 | with:
50 | fetch-depth: 0
51 | - name: Build
52 | run: |
53 | cd /home/runner/work/shelly-homekit/shelly-homekit
54 | git config --global --add safe.directory /home/runner/work/shelly-homekit/shelly-homekit
55 | make ${{ matrix.model }} LOCAL=1 RELEASE=1 RELEASE_SUFFIX=$(.github/version.py --suffix)
56 | - name: Upload firmware artifacts
57 | uses: actions/upload-artifact@v4
58 | with:
59 | name: release-${{ matrix.model }}
60 | path: releases/**/shelly-homekit-${{ matrix.model }}.zip
61 | if-no-files-found: warn
62 | merge:
63 | needs: build
64 | runs-on: ubuntu-latest
65 | steps:
66 | - name: Merge Artifacts
67 | uses: actions/upload-artifact/merge@v4
68 | with:
69 | name: all-releases
70 | pattern: release-*
71 |
--------------------------------------------------------------------------------
/.github/workflows/check-format.yaml:
--------------------------------------------------------------------------------
1 | name: check format
2 | on:
3 | push:
4 | pull_request:
5 | jobs:
6 | check-format:
7 | runs-on: ubuntu-22.04
8 | steps:
9 | - name: Checkout code
10 | uses: actions/checkout@v4
11 | with:
12 | fetch-depth: 0
13 | - name: Check formatting
14 | run: make check-format
15 |
--------------------------------------------------------------------------------
/.github/workflows/howto.build:
--------------------------------------------------------------------------------
1 |
2 | image=ghcr.io/markirb/esp32-build:4.4.1-r7
3 | docker build -t $image -f Dockerfile-esp32-build .
4 | docker push $image
5 |
6 | image=ghcr.io/markirb/mos:latest
7 | docker build -t $image -f Dockerfile-mos .
8 | docker push $image
9 |
--------------------------------------------------------------------------------
/.github/workflows/stale.yml:
--------------------------------------------------------------------------------
1 | name: Mark stale issues.
2 |
3 | on:
4 | schedule:
5 | - cron: "30 1 * * *"
6 |
7 | jobs:
8 | stale:
9 |
10 | runs-on: ubuntu-latest
11 |
12 | steps:
13 | - uses: actions/stale@v3
14 | with:
15 | repo-token: ${{ secrets.GITHUB_TOKEN }}
16 | exempt-all-pr-milestones: true
17 | exempt-issue-labels: 'enhancement, new-device-support, new-HAP-type, confirmed-bug, waiting-for-rojer, needs deeper look'
18 | stale-issue-message: 'This issue is stale because it has been open 3 weeks with no activity. Comment or this will be closed in 1 week.'
19 | stale-issue-label: 'stale'
20 | close-issue-message: 'This issue has now been closed, as no update was provided after it was marked stale. Feel free to provide updates to reopen this issue.'
21 | days-before-issue-stale: 21
22 | days-before-issue-close: 7
23 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | binlibs/
2 | build/
3 | build_*/
4 | deps/
5 | releases/
6 | .vscode/
7 | .DS_Store
8 | core-*
9 | *.gz
10 | *.zip
11 | fs/conf*.json
12 | flash-shelly.auth.yaml
13 | *.cfg.yaml
14 | .venv
15 |
--------------------------------------------------------------------------------
/AUTHORS.md:
--------------------------------------------------------------------------------
1 | # Shelly-HomeKit authors
2 |
3 | The following people have contributed to the project (in chronological order):
4 |
5 | * [Deomid "rojer" Ryabkov](https://github.com/rojer)
6 | * [Andy Blackburn](https://github.com/andyblac)
7 | * [Thorsten Eurich](https://github.com/eurich)
8 | * [Dominik Schemhaus](https://github.com/schemhad)
9 | * [Timothy Langer](https://github.com/ZeeVox)
10 | * [Timo Schilling](https://github.com/timoschilling)
11 | * [Josef Blösl](https://github.com/jobl1978)
12 | * [Markus Kirberg](https://github.com/markirb)
13 |
14 | Full list of contributors [here](https://github.com/mongoose-os-apps/shelly-homekit/graphs/contributors).
15 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Copyright (c) Shelly-HomeKit Contributors
2 | All rights reserved
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License");
5 | you may not use this file except in compliance with the License.
6 | You may obtain a copy of the License at
7 |
8 | http://www.apache.org/licenses/LICENSE-2.0
9 |
10 | Unless required by applicable law or agreed to in writing, software
11 | distributed under the License is distributed on an "AS IS" BASIS,
12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | See the License for the specific language governing permissions and
14 | limitations under the License.
15 |
--------------------------------------------------------------------------------
/docs/SDNT1608-0.1-10.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mongoose-os-apps/shelly-homekit/4569119f20bcad1dafa9d30102973c1657e7f68d/docs/SDNT1608-0.1-10.png
--------------------------------------------------------------------------------
/fs/favicon.ico.gz:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mongoose-os-apps/shelly-homekit/4569119f20bcad1dafa9d30102973c1657e7f68d/fs/favicon.ico.gz
--------------------------------------------------------------------------------
/fs_src/logo.svg:
--------------------------------------------------------------------------------
1 |
26 |
--------------------------------------------------------------------------------
/fs_src/sha256.js:
--------------------------------------------------------------------------------
1 | // https://github.com/geraintluff/sha256; Public Domain
2 | let sha256 = function a(b){function c(a,b){return a>>>b|a<<32-b}for(var d,e,f=Math.pow,g=f(2,32),h="length",i="",j=[],k=8*b[h],l=a.h=a.h||[],m=a.k=a.k||[],n=m[h],o={},p=2;64>n;p++)if(!o[p]){for(d=0;313>d;d+=p)o[d]=p;l[n]=f(p,.5)*g|0,m[n++]=f(p,1/3)*g|0}for(b+="\x80";b[h]%64-56;)b+="\x00";for(d=0;d>8)return;j[d>>2]|=e<<(3-d)%4*8}for(j[j[h]]=k/g|0,j[j[h]]=k,e=0;ed;d++){var s=q[d-15],t=q[d-2],u=l[0],v=l[4],w=l[7]+(c(v,6)^c(v,11)^c(v,25))+(v&l[5]^~v&l[6])+m[d]+(q[d]=16>d?q[d]:q[d-16]+(c(s,7)^c(s,18)^s>>>3)+q[d-7]+(c(t,17)^c(t,19)^t>>>10)|0),x=(c(u,2)^c(u,13)^c(u,22))+(u&l[1]^u&l[2]^l[1]&l[2]);l=[w+x|0].concat(l),l[4]=l[4]+w|0}for(d=0;8>d;d++)l[d]=l[d]+r[d]|0}for(d=0;8>d;d++)for(e=3;e+1;e--){var y=l[d]>>8*e&255;i+=(16>y?0:"")+y.toString(16)}return i};
3 |
--------------------------------------------------------------------------------
/libreset/include/shelly_reset.hpp:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) Shelly-HomeKit Contributors
3 | * All rights reserved
4 | *
5 | * Licensed under the Apache License, Version 2.0 (the "License");
6 | * you may not use this file except in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | */
17 |
18 | #pragma once
19 |
20 | #include "shelly_input.hpp"
21 |
22 | namespace shelly {
23 |
24 | // Reset device WiFi and auth settings.
25 | void ResetDevice(int out_gpio);
26 |
27 | // Wipe all device configuration, including WiFi.
28 | bool WipeDevice();
29 |
30 | // Wipe device before reverting to stock FW.
31 | // Preserves WiFi STA config.
32 | void WipeDeviceRevertToStock();
33 |
34 | // Handler for input reset sequence.
35 | void HandleInputResetSequence(Input *in, int out_gpio, Input::Event ev,
36 | bool cur_state);
37 |
38 | bool IsSoftReboot();
39 |
40 | bool IsFailsafeMode();
41 |
42 | void SanitizeSysConfig();
43 |
44 | // Check if device is in a reboot loop (deliberate or not) and perform reset.
45 | void CheckRebootCounter();
46 |
47 | } // namespace shelly
48 |
--------------------------------------------------------------------------------
/libreset/mos.yml:
--------------------------------------------------------------------------------
1 | description: Shelly device reset library
2 | type: lib
3 | version: 1.0.0
4 |
5 | sources:
6 | - src
7 |
8 | includes:
9 | - include
10 |
11 | no_implicit_init_deps: true
12 | # Execute as early as possible, before pretty much anything else.
13 | init_after:
14 | - core
15 | init_before:
16 | - adc
17 | - i2c
18 | - file-logger
19 | - homekit-adk
20 | - http-server
21 | - ota-http-server
22 | - rpc-*
23 | - wifi
24 |
25 | manifest_version: 2019-07-28
26 |
--------------------------------------------------------------------------------
/src/ADE7953/shelly_pm_ade7953.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) Shelly-HomeKit Contributors
3 | * All rights reserved
4 | *
5 | * Licensed under the Apache License, Version 2.0 (the "License");
6 | * you may not use this file except in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | */
17 |
18 | #include "shelly_pm_ade7953.hpp"
19 |
20 | #include
21 |
22 | #include "mgos.hpp"
23 | #include "mgos_ade7953.h"
24 |
25 | namespace shelly {
26 |
27 | struct mgos_ade7953 *s_ade7953 = NULL;
28 |
29 | ADE7953PowerMeter::ADE7953PowerMeter(int id, struct mgos_ade7953 *ade7953,
30 | int channel)
31 | : PowerMeter(id),
32 | ade7953_(ade7953),
33 | channel_(channel),
34 | acc_timer_(std::bind(&ADE7953PowerMeter::AEAAccumulateTimerCB, this)) {
35 | }
36 |
37 | ADE7953PowerMeter::~ADE7953PowerMeter() {
38 | }
39 |
40 | Status ADE7953PowerMeter::Init() {
41 | acc_timer_.Reset(10000, MGOS_TIMER_REPEAT);
42 | return Status::OK();
43 | }
44 |
45 | StatusOr ADE7953PowerMeter::GetPowerW() {
46 | float apa = 0;
47 | if (!mgos_ade7953_get_apower(ade7953_, channel_, &apa)) {
48 | return mgos::Errorf(STATUS_UNAVAILABLE, "Failed to read %s", "AP");
49 | }
50 | apa = std::fabs(apa);
51 | if (apa < 1) apa = 0; // Suppress noise.
52 | return apa;
53 | }
54 |
55 | StatusOr ADE7953PowerMeter::GetEnergyWH() {
56 | return GetEnergyWH(false /* reset */);
57 | }
58 |
59 | StatusOr ADE7953PowerMeter::GetEnergyWH(bool reset) {
60 | float aea = 0;
61 | if (!mgos_ade7953_get_aenergy(ade7953_, channel_, reset, &aea)) {
62 | return mgos::Errorf(STATUS_UNAVAILABLE, "Failed to read %s", "AE");
63 | }
64 | float res = aea_acc_ + std::fabs(aea);
65 | if (reset) {
66 | aea_acc_ = res;
67 | }
68 | return res;
69 | }
70 |
71 | void ADE7953PowerMeter::AEAAccumulateTimerCB() {
72 | GetEnergyWH(true /* reset */);
73 | }
74 |
75 | } // namespace shelly
76 |
--------------------------------------------------------------------------------
/src/ADE7953/shelly_pm_ade7953.hpp:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) Shelly-HomeKit Contributors
3 | * All rights reserved
4 | *
5 | * Licensed under the Apache License, Version 2.0 (the "License");
6 | * you may not use this file except in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | */
17 |
18 | #include "shelly_pm.hpp"
19 |
20 | #include
21 |
22 | #include "mgos.hpp"
23 | #include "mgos_ade7953.h"
24 |
25 | namespace shelly {
26 |
27 | class ADE7953PowerMeter : public PowerMeter {
28 | public:
29 | ADE7953PowerMeter(int id, struct mgos_ade7953 *ade7953, int channel);
30 | virtual ~ADE7953PowerMeter();
31 |
32 | Status Init() override;
33 | StatusOr GetPowerW() override;
34 | StatusOr GetEnergyWH() override;
35 |
36 | private:
37 | StatusOr GetEnergyWH(bool reset);
38 | void AEAAccumulateTimerCB();
39 |
40 | struct mgos_ade7953 *const ade7953_;
41 | const int channel_;
42 | float aea_acc_ = 0; // Accumulated active energy.
43 | mgos::Timer acc_timer_;
44 | };
45 |
46 | } // namespace shelly
47 |
--------------------------------------------------------------------------------
/src/BL0937/shelly_pm_bl0937.hpp:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) Shelly-HomeKit Contributors
3 | * All rights reserved
4 | *
5 | * Licensed under the Apache License, Version 2.0 (the "License");
6 | * you may not use this file except in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | */
17 |
18 | #include "shelly_pm.hpp"
19 |
20 | #include "mgos_timers.hpp"
21 |
22 | namespace shelly {
23 |
24 | class BL0937PowerMeter : public PowerMeter {
25 | public:
26 | BL0937PowerMeter(int id, int cf_pin, int cf1_pin, int sel_pin, int meas_time,
27 | float apc);
28 | virtual ~BL0937PowerMeter();
29 |
30 | Status Init() override;
31 | StatusOr GetPowerW() override;
32 | StatusOr GetEnergyWH() override;
33 |
34 | private:
35 | static void GPIOIntHandler(int pin, void *arg);
36 | void MeasureTimerCB();
37 |
38 | const int cf_pin_, cf1_pin_, sel_pin_, meas_time_;
39 | const float apc_;
40 |
41 | volatile uint32_t cf_count_ = 0, cf1_count_ = 0;
42 | int64_t meas_start_ = 0;
43 |
44 | float apa_ = 0; // Last active power reading, W.
45 | float aea_ = 0; // Accumulated active energy, Wh.
46 |
47 | mgos::Timer meas_timer_;
48 | };
49 |
50 | } // namespace shelly
51 |
--------------------------------------------------------------------------------
/src/BL0942/shelly_pm_bl0942.hpp:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) Shelly-HomeKit Contributors
3 | * All rights reserved
4 | *
5 | * Licensed under the Apache License, Version 2.0 (the "License");
6 | * you may not use this file except in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | */
17 |
18 | #include "shelly_pm.hpp"
19 |
20 | #include "mgos_timers.hpp"
21 |
22 | namespace shelly {
23 |
24 | struct bl0942_cfg {
25 | float voltage_scale;
26 | float current_scale;
27 | float apower_scale;
28 | float aenergy_scale;
29 | };
30 |
31 | class BL0942PowerMeter : public PowerMeter {
32 | public:
33 | BL0942PowerMeter(int id, int tx_pin, int rx_pin, int meas_time, int uart_no,
34 | const bl0942_cfg &cfg);
35 | virtual ~BL0942PowerMeter();
36 |
37 | Status Init() override;
38 | StatusOr GetPowerW() override;
39 | StatusOr GetEnergyWH() override;
40 |
41 | private:
42 | void MeasureTimerCB();
43 |
44 | const int tx_pin_, rx_pin_, meas_time_, uart_no_;
45 | const bl0942_cfg cfg_;
46 |
47 | float apa_ = 0; // Last active power reading, W.
48 | float aea_ = 0; // Accumulated active energy, Wh.
49 | //
50 | bool ReadReg(uint8_t reg, uint8_t *rx_buf, size_t len);
51 | bool WriteReg(uint8_t reg, uint32_t val);
52 |
53 | mgos::Timer meas_timer_;
54 | };
55 |
56 | } // namespace shelly
57 |
--------------------------------------------------------------------------------
/src/DHT/shelly_dht_sensor.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) Shelly-HomeKit Contributors
3 | * All rights reserved
4 | *
5 | * Licensed under the Apache License, Version 2.0 (the "License");
6 | * you may not use this file except in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | */
17 |
18 | #include "shelly_dht_sensor.hpp"
19 | #include
20 | #include "mgos_hal.h"
21 |
22 | namespace shelly {
23 |
24 | std::vector> DiscoverDHTSensors(int in, int out) {
25 | std::vector> sensors;
26 |
27 | std::unique_ptr dht(new DHTSensor(in, out));
28 | auto status = dht->Init();
29 | if (status == Status::OK()) {
30 | sensors.push_back(std::move(dht));
31 | } else {
32 | LOG(LL_ERROR, ("dht init failed: %s", status.ToString().c_str()));
33 | }
34 | return sensors;
35 | }
36 |
37 | DHTSensor::DHTSensor(uint8_t pin_in, uint8_t pin_out)
38 | : pin_in_(pin_in),
39 | pin_out_(pin_out),
40 | meas_timer_(std::bind(&DHTSensor::UpdateTemperatureCB, this)) {
41 | result_ = mgos::Errorf(STATUS_UNAVAILABLE, "Not updated yet");
42 | result_humidity_ = mgos::Errorf(STATUS_UNAVAILABLE, "Not updated yet");
43 | }
44 |
45 | DHTSensor::~DHTSensor() {
46 | }
47 |
48 | Status DHTSensor::Init() {
49 | dht = mgos_dht_create_separate_io(pin_in_, pin_out_, DHT21);
50 |
51 | if (dht == NULL) {
52 | return mgos::Errorf(STATUS_NOT_FOUND, "dht sensor init unsuccesfull");
53 | }
54 |
55 | size_t tries =
56 | 2; // first read was observed to be not successfull, reason unknown
57 | mgos_dht_stats stats;
58 | for (size_t i = 0; i < tries; i++) {
59 | result_ = mgos_dht_get_temp(dht);
60 | if (mgos_dht_getStats(dht, &stats)) {
61 | if (stats.read_success >= 1) {
62 | return Status::OK();
63 | } else if (i != (tries - 1)) {
64 | mgos_msleep(2 *
65 | 1000); // try again after wait time of MGOs_DHT_READ_DELAY
66 | }
67 | }
68 | }
69 |
70 | return mgos::Errorf(STATUS_NOT_FOUND, "No DHT Sensor found");
71 | }
72 |
73 | void DHTSensor::StartUpdating(int interval) {
74 | meas_timer_.Reset(interval, MGOS_TIMER_REPEAT | MGOS_TIMER_RUN_NOW);
75 | }
76 |
77 | void DHTSensor::StopUpdating() {
78 | meas_timer_.Clear();
79 | }
80 |
81 | StatusOr DHTSensor::GetTemperature() {
82 | return result_;
83 | }
84 |
85 | StatusOr DHTSensor::GetHumidity() {
86 | return result_humidity_;
87 | }
88 |
89 | void DHTSensor::UpdateTemperatureCB() {
90 | float result = mgos_dht_get_temp(dht);
91 | float result_humidity = mgos_dht_get_humidity(dht);
92 |
93 | // check values for validity
94 | if (((result == 0) and (result_humidity == 0)) or isnan(result) or
95 | isnan(result_humidity)) {
96 | // error during readout do nothing for now
97 | LOG(LL_INFO, ("DHT: invalid value received"));
98 | return;
99 | }
100 |
101 | result_ = result;
102 | result_humidity_ = result_humidity;
103 |
104 | if (notifier_) {
105 | notifier_();
106 | }
107 | if (notifier_hum_) {
108 | notifier_hum_();
109 | }
110 | }
111 |
112 | } // namespace shelly
113 |
--------------------------------------------------------------------------------
/src/DHT/shelly_dht_sensor.hpp:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) Shelly-HomeKit Contributors
3 | * All rights reserved
4 | *
5 | * Licensed under the Apache License, Version 2.0 (the "License");
6 | * you may not use this file except in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | */
17 |
18 | #pragma once
19 |
20 | #include "shelly_temp_sensor.hpp"
21 |
22 | #include "mgos_timers.hpp"
23 |
24 | #include
25 |
26 | #include
27 |
28 | namespace shelly {
29 |
30 | std::vector> DiscoverDHTSensors(int in, int out);
31 |
32 | class DHTSensor : public HumidityTempSensor {
33 | public:
34 | DHTSensor(uint8_t pin_in, uint8_t pin_out);
35 | virtual ~DHTSensor();
36 |
37 | Status Init();
38 | StatusOr GetTemperature() override;
39 | StatusOr GetHumidity() override;
40 |
41 | virtual void StartUpdating(int interval) override;
42 | virtual void StopUpdating() override;
43 |
44 | private:
45 | uint8_t pin_in_;
46 | uint8_t pin_out_;
47 |
48 | mgos::Timer meas_timer_;
49 |
50 | mgos_dht *dht;
51 |
52 | void UpdateTemperatureCB();
53 | StatusOr result_;
54 | StatusOr result_humidity_;
55 | };
56 |
57 | } // namespace shelly
58 |
--------------------------------------------------------------------------------
/src/DS18XXX/shelly_temp_sensor_ow.hpp:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) Shelly-HomeKit Contributors
3 | * All rights reserved
4 | *
5 | * Licensed under the Apache License, Version 2.0 (the "License");
6 | * you may not use this file except in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | */
17 |
18 | #pragma once
19 |
20 | #include "shelly_temp_sensor.hpp"
21 |
22 | #include
23 |
24 | #include "mgos_timers.hpp"
25 |
26 | struct mgos_onewire;
27 |
28 | namespace shelly {
29 |
30 | class Onewire {
31 | public:
32 | struct ROM {
33 | uint64_t family : 8;
34 | uint64_t serial : 48;
35 | uint64_t crc : 8;
36 |
37 | ROM() : family(0), serial(0), crc(0) {
38 | }
39 | };
40 |
41 | Onewire(int pin_in, int pin_out);
42 | ~Onewire();
43 | struct mgos_onewire *Get();
44 | std::vector> DiscoverAll();
45 |
46 | private:
47 | struct mgos_onewire *ow_;
48 |
49 | int pin_out_;
50 | std::unique_ptr NextAvailableSensor(int type);
51 | };
52 |
53 | class TempSensorDS18XXX : public TempSensor {
54 | public:
55 | TempSensorDS18XXX(struct mgos_onewire *ow, const Onewire::ROM &rom);
56 | virtual ~TempSensorDS18XXX();
57 |
58 | Status Init();
59 | StatusOr GetTemperature() override;
60 |
61 | static bool SupportsFamily(uint8_t family);
62 | virtual void StartUpdating(int interval) override;
63 | virtual void StopUpdating() override;
64 |
65 | private:
66 | struct __attribute__((__packed__)) Scratchpad {
67 | int16_t temperature;
68 | uint8_t th;
69 | uint8_t tl;
70 | union {
71 | uint8_t rsvd_1 : 5;
72 | uint8_t resolution : 2;
73 | uint8_t rsvd_0 : 1;
74 | uint8_t val;
75 | } cfg;
76 | uint8_t rfu;
77 | uint8_t count_remain;
78 | uint8_t count_per_c;
79 | uint8_t crc;
80 |
81 | int GetResolution() const;
82 | int GetConversionTimeMs() const;
83 | };
84 |
85 | void ReadTemperatureCB();
86 | void UpdateTemperatureCB();
87 |
88 | StatusOr ReadScratchpad();
89 | bool ReadPowerSupply();
90 |
91 | struct mgos_onewire *ow_ = nullptr;
92 | const Onewire::ROM rom_;
93 | StatusOr result_;
94 |
95 | mgos::Timer meas_timer_;
96 | mgos::Timer read_timer_;
97 | int conversion_time_ms_ = 750;
98 | };
99 |
100 | } // namespace shelly
101 |
--------------------------------------------------------------------------------
/src/Shelly1/shelly_init.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) Shelly-HomeKit Contributors
3 | * All rights reserved
4 | *
5 | * Licensed under the Apache License, Version 2.0 (the "License");
6 | * you may not use this file except in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | */
17 |
18 | #include "mgos_hap.h"
19 |
20 | #include "shelly_dht_sensor.hpp"
21 | #include "shelly_hap_garage_door_opener.hpp"
22 | #include "shelly_hap_input.hpp"
23 | #include "shelly_input_pin.hpp"
24 | #include "shelly_main.hpp"
25 | #include "shelly_temp_sensor_ow.hpp"
26 |
27 | namespace shelly {
28 |
29 | static std::unique_ptr s_onewire;
30 | static std::vector> sensors;
31 |
32 | void CreatePeripherals(std::vector> *inputs,
33 | std::vector> *outputs,
34 | std::vector> *pms UNUSED_ARG,
35 | std::unique_ptr *sys_temp UNUSED_ARG) {
36 | outputs->emplace_back(new OutputPin(1, 4, 1));
37 | auto *in1 = new InputPin(1, 5, 1, MGOS_GPIO_PULL_NONE, true);
38 | in1->AddHandler(std::bind(&HandleInputResetSequence, in1, 4, _1, _2));
39 | in1->Init();
40 | inputs->emplace_back(in1);
41 |
42 | int pin_in = 3;
43 | int pin_out = 0;
44 |
45 | if (DetectAddon(pin_in, pin_out)) {
46 | s_onewire.reset(new Onewire(pin_in, pin_out));
47 | sensors = s_onewire->DiscoverAll();
48 | if (sensors.empty()) {
49 | s_onewire.reset();
50 | sensors = DiscoverDHTSensors(pin_in, pin_out);
51 | }
52 | if (sensors.empty()) {
53 | // No sensors detected, we assume to use addon as input for switch or
54 | // closed/open sensor
55 | auto *in2 = new InputPin(2, pin_in, 0, MGOS_GPIO_PULL_NONE, false);
56 | in2->Init();
57 | inputs->emplace_back(in2);
58 | }
59 | }
60 | }
61 |
62 | void CreateComponents(std::vector> *comps,
63 | std::vector> *accs,
64 | HAPAccessoryServerRef *svr) {
65 | bool gdo_mode = mgos_sys_config_get_shelly_mode() == (int) Mode::kGarageDoor;
66 | bool ext_sensor_switch = (FindInput(2) != nullptr);
67 | bool addon_input = !gdo_mode && ext_sensor_switch;
68 | bool single_accessory =
69 | sensors.empty() && !addon_input &&
70 | (mgos_sys_config_get_sw1_in_mode() != (int) InMode::kDetached);
71 | if (gdo_mode) {
72 | hap::CreateHAPGDO(1, FindInput(1), FindInput(2), FindOutput(1),
73 | FindOutput(1), mgos_sys_config_get_gdo1(), comps, accs,
74 | svr, true);
75 | } else {
76 | CreateHAPSwitch(1, mgos_sys_config_get_sw1(), mgos_sys_config_get_in1(),
77 | comps, accs, svr, single_accessory);
78 | }
79 |
80 | if (!sensors.empty()) {
81 | CreateHAPSensors(&sensors, comps, accs, svr);
82 | } else if (addon_input) {
83 | hap::CreateHAPInput(2, mgos_sys_config_get_in2(), comps, accs, svr);
84 | }
85 | }
86 |
87 | } // namespace shelly
88 |
--------------------------------------------------------------------------------
/src/Shelly1L/shelly_init.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) Shelly-HomeKit Contributors
3 | * All rights reserved
4 | *
5 | * Licensed under the Apache License, Version 2.0 (the "License");
6 | * you may not use this file except in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | */
17 |
18 | #include "shelly_hap_input.hpp"
19 | #include "shelly_input.hpp"
20 | #include "shelly_main.hpp"
21 | #include "shelly_noisy_input_pin.hpp"
22 | #include "shelly_pm_bl0937.hpp"
23 | #include "shelly_switch.hpp"
24 | #include "shelly_sys_led_btn.hpp"
25 | #include "shelly_temp_sensor_ntc.hpp"
26 |
27 | namespace shelly {
28 |
29 | void CreatePeripherals(std::vector> *inputs,
30 | std::vector> *outputs,
31 | std::vector> *pms,
32 | std::unique_ptr *sys_temp) {
33 | outputs->emplace_back(new OutputPin(1, 5, 1));
34 | auto *in1 = new NoisyInputPin(1, 4, 1, MGOS_GPIO_PULL_NONE, true);
35 | in1->AddHandler(std::bind(&HandleInputResetSequence, in1, 5, _1, _2));
36 | in1->Init();
37 | inputs->emplace_back(in1);
38 | auto *in2 = new NoisyInputPin(2, 14, 1, MGOS_GPIO_PULL_NONE, false);
39 | in2->Init();
40 | inputs->emplace_back(in2);
41 | #if 0 // 1L uses BL0937 in current-only mode. This is not yet supported.
42 | std::unique_ptr pm(new BL0937PowerMeter(1, -1, 4, -1));
43 | if (pm->Init().ok()) {
44 | pms->emplace_back(std::move(pm));
45 | }
46 | #else
47 | (void) pms;
48 | #endif
49 | sys_temp->reset(new TempSensorSDNT1608X103F3950(0, 3.3f, 33000.0f));
50 |
51 | InitSysLED(LED_GPIO, LED_ON);
52 | InitSysBtn(BTN_GPIO, BTN_DOWN);
53 | }
54 |
55 | void CreateComponents(std::vector> *comps,
56 | std::vector> *accs,
57 | HAPAccessoryServerRef *svr) {
58 | CreateHAPSwitch(1, mgos_sys_config_get_sw1(), mgos_sys_config_get_in1(),
59 | comps, accs, svr, false);
60 | if (mgos_sys_config_get_sw1_in_mode() == (int) InMode::kEdgeBoth ||
61 | mgos_sys_config_get_sw1_in_mode() == (int) InMode::kActivation) {
62 | ShellySwitch *sw = reinterpret_cast(comps->back().get());
63 | sw->AddInput(FindInput(2));
64 | } else {
65 | hap::CreateHAPInput(2, mgos_sys_config_get_in2(), comps, accs, svr);
66 | }
67 | }
68 |
69 | } // namespace shelly
70 |
--------------------------------------------------------------------------------
/src/Shelly2/shelly_init.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) Shelly-HomeKit Contributors
3 | * All rights reserved
4 | *
5 | * Licensed under the Apache License, Version 2.0 (the "License");
6 | * you may not use this file except in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | */
17 |
18 | #include
19 |
20 | #include "shelly_hap_garage_door_opener.hpp"
21 | #include "shelly_input_pin.hpp"
22 | #include "shelly_main.hpp"
23 |
24 | namespace shelly {
25 |
26 | void CreatePeripherals(std::vector> *inputs,
27 | std::vector> *outputs,
28 | std::vector> *pms,
29 | std::unique_ptr *sys_temp) {
30 | outputs->emplace_back(new OutputPin(1, 4, 1));
31 | outputs->emplace_back(new OutputPin(2, 5, 1));
32 | auto *in1 = new InputPin(1, 12, 1, MGOS_GPIO_PULL_NONE, true);
33 | in1->AddHandler(std::bind(&HandleInputResetSequence, in1, 4, _1, _2));
34 | in1->Init();
35 | inputs->emplace_back(in1);
36 | auto *in2 = new InputPin(2, 14, 1, MGOS_GPIO_PULL_NONE, false);
37 | in2->Init();
38 | inputs->emplace_back(in2);
39 | (void) sys_temp;
40 | (void) pms;
41 | }
42 |
43 | void CreateComponents(std::vector> *comps,
44 | std::vector> *accs,
45 | HAPAccessoryServerRef *svr) {
46 | if (mgos_sys_config_get_shelly_mode() == (int) Mode::kGarageDoor) {
47 | hap::CreateHAPGDO(1, FindInput(1), FindInput(2), FindOutput(1),
48 | FindOutput(2), mgos_sys_config_get_gdo1(), comps, accs,
49 | svr, true /* single accessory */);
50 | return;
51 | }
52 |
53 | // Use legacy layout if upgraded from an older version (pre-2.1).
54 | // However, presence of detached inputs overrides it.
55 | bool compat_20 = (mgos_sys_config_get_shelly_legacy_hap_layout() &&
56 | mgos_sys_config_get_sw1_in_mode() != 3 &&
57 | mgos_sys_config_get_sw2_in_mode() != 3);
58 | if (!compat_20) {
59 | CreateHAPSwitch(1, mgos_sys_config_get_sw1(), mgos_sys_config_get_in1(),
60 | comps, accs, svr, false /* to_pri_acc */);
61 | CreateHAPSwitch(2, mgos_sys_config_get_sw2(), mgos_sys_config_get_in2(),
62 | comps, accs, svr, false /* to_pri_acc */);
63 | } else {
64 | CreateHAPSwitch(2, mgos_sys_config_get_sw2(), mgos_sys_config_get_in2(),
65 | comps, accs, svr, true /* to_pri_acc */);
66 | CreateHAPSwitch(1, mgos_sys_config_get_sw1(), mgos_sys_config_get_in1(),
67 | comps, accs, svr, true /* to_pri_acc */);
68 | std::reverse(comps->begin(), comps->end());
69 | }
70 | }
71 |
72 | } // namespace shelly
73 |
--------------------------------------------------------------------------------
/src/Shelly25/shelly_init_components.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) Shelly-HomeKit Contributors
3 | * All rights reserved
4 | *
5 | * Licensed under the Apache License, Version 2.0 (the "License");
6 | * you may not use this file except in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | */
17 |
18 | #include
19 |
20 | #include "shelly_hap_garage_door_opener.hpp"
21 | #include "shelly_hap_input.hpp"
22 | #include "shelly_hap_window_covering.hpp"
23 | #include "shelly_main.hpp"
24 |
25 | namespace shelly {
26 |
27 | void CreateComponents(std::vector> *comps,
28 | std::vector> *accs,
29 | HAPAccessoryServerRef *svr) {
30 | if (mgos_sys_config_get_shelly_mode() == (int) Mode::kRollerShutter) {
31 | hap::CreateHAPWC(1, FindInput(1), FindInput(2), FindOutput(1),
32 | FindOutput(2), FindPM(1), FindPM(2),
33 | mgos_sys_config_get_wc1(), mgos_sys_config_get_in1(),
34 | mgos_sys_config_get_in2(), comps, accs, svr);
35 | return;
36 | }
37 |
38 | if (mgos_sys_config_get_shelly_mode() == (int) Mode::kGarageDoor) {
39 | hap::CreateHAPGDO(1, FindInput(1), FindInput(2), FindOutput(1),
40 | FindOutput(2), mgos_sys_config_get_gdo1(), comps, accs,
41 | svr, true /* single accessory */);
42 | return;
43 | }
44 | // Use legacy layout if upgraded from an older version (pre-2.1).
45 | // However, presence of detached inputs overrides it.
46 | bool compat_20 = (mgos_sys_config_get_shelly_legacy_hap_layout() &&
47 | mgos_sys_config_get_sw1_in_mode() != 3 &&
48 | mgos_sys_config_get_sw2_in_mode() != 3);
49 | if (!compat_20) {
50 | CreateHAPSwitch(1, mgos_sys_config_get_sw1(), mgos_sys_config_get_in1(),
51 | comps, accs, svr, false /* to_pri_acc */);
52 | CreateHAPSwitch(2, mgos_sys_config_get_sw2(), mgos_sys_config_get_in2(),
53 | comps, accs, svr, false /* to_pri_acc */);
54 | } else {
55 | CreateHAPSwitch(2, mgos_sys_config_get_sw2(), mgos_sys_config_get_in2(),
56 | comps, accs, svr, true /* to_pri_acc */);
57 | CreateHAPSwitch(1, mgos_sys_config_get_sw1(), mgos_sys_config_get_in1(),
58 | comps, accs, svr, true /* to_pri_acc */);
59 | std::reverse(comps->begin(), comps->end());
60 | }
61 | }
62 |
63 | } // namespace shelly
64 |
--------------------------------------------------------------------------------
/src/ShellyColorBulb/shelly_init.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) Shelly-HomeKit Contributors
3 | * All rights reserved
4 | *
5 | * Licensed under the Apache License, Version 2.0 (the "License");
6 | * you may not use this file except in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | */
17 |
18 | #include "shelly_cct_controller.hpp"
19 | #include "shelly_hap_input.hpp"
20 | #include "shelly_hap_light_bulb.hpp"
21 | #include "shelly_input_pin.hpp"
22 | #include "shelly_main.hpp"
23 | #include "shelly_rgbw_controller.hpp"
24 |
25 | namespace shelly {
26 |
27 | void CreatePeripherals(UNUSED_ARG std::vector> *inputs,
28 | std::vector> *outputs,
29 | UNUSED_ARG std::vector> *pms,
30 | UNUSED_ARG std::unique_ptr *sys_temp) {
31 | outputs->emplace_back(new OutputPin(1, 13, 1)); // R
32 | outputs->emplace_back(new OutputPin(2, 12, 1)); // G
33 | outputs->emplace_back(new OutputPin(3, 14, 1)); // B
34 | outputs->emplace_back(new OutputPin(4, 5, 1)); // W
35 | }
36 |
37 | void CreateComponents(std::vector> *comps,
38 | std::vector> *accs,
39 | HAPAccessoryServerRef *svr) {
40 | std::unique_ptr lightbulb_controller;
41 | std::unique_ptr hap_light;
42 | auto *lb_cfg = (struct mgos_config_lb *) mgos_sys_config_get_lb1();
43 |
44 | lightbulb_controller.reset(new RGBWController(
45 | lb_cfg, FindOutput(1), FindOutput(2), FindOutput(3), FindOutput(4)));
46 |
47 | hap_light.reset(new hap::LightBulb(
48 | 1, nullptr, std::move(lightbulb_controller), lb_cfg, false));
49 |
50 | if (hap_light == nullptr || !hap_light->Init().ok()) {
51 | return;
52 | }
53 |
54 | mgos::hap::Accessory *pri_acc = accs->front().get();
55 | shelly::hap::LightBulb *light_ref = hap_light.get();
56 | hap_light->set_primary(true);
57 | pri_acc->SetCategory(kHAPAccessoryCategory_Lighting);
58 | pri_acc->AddService(hap_light.get());
59 | pri_acc->SetIdentifyCB(
60 | [light_ref](const HAPAccessoryIdentifyRequest *request UNUSED_ARG) {
61 | light_ref->Identify();
62 | return kHAPError_None;
63 | });
64 |
65 | comps->push_back(std::move(hap_light));
66 | }
67 | } // namespace shelly
--------------------------------------------------------------------------------
/src/ShellyDuo/shelly_init.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) Shelly-HomeKit Contributors
3 | * All rights reserved
4 | *
5 | * Licensed under the Apache License, Version 2.0 (the "License");
6 | * you may not use this file except in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | */
17 |
18 | #include "shelly_cct_controller.hpp"
19 | #include "shelly_hap_input.hpp"
20 | #include "shelly_hap_light_bulb.hpp"
21 | #include "shelly_input_pin.hpp"
22 | #include "shelly_light_bulb_controller.hpp"
23 | #include "shelly_main.hpp"
24 |
25 | namespace shelly {
26 |
27 | void CreatePeripherals(UNUSED_ARG std::vector> *inputs,
28 | std::vector> *outputs,
29 | UNUSED_ARG std::vector> *pms,
30 | UNUSED_ARG std::unique_ptr *sys_temp) {
31 | outputs->emplace_back(new OutputPin(1, 5, 1));
32 | outputs->emplace_back(new OutputPin(2, 4, 1));
33 | }
34 |
35 | void CreateComponents(std::vector> *comps,
36 | std::vector> *accs,
37 | HAPAccessoryServerRef *svr UNUSED_ARG) {
38 | std::unique_ptr lightbulb_controller;
39 | std::unique_ptr hap_light;
40 | auto *lb_cfg = (struct mgos_config_lb *) mgos_sys_config_get_lb1();
41 |
42 | lightbulb_controller.reset(
43 | new CCTController(lb_cfg, FindOutput(1), FindOutput(2)));
44 |
45 | hap_light.reset(new hap::LightBulb(
46 | 1, nullptr, std::move(lightbulb_controller), lb_cfg, false));
47 |
48 | if (hap_light == nullptr || !hap_light->Init().ok()) {
49 | return;
50 | }
51 |
52 | // Use adaptive lightning when possible (CCT)
53 | std::unique_ptr adaptive_light;
54 | adaptive_light.reset(new hap::AdaptiveLighting(hap_light.get(), lb_cfg));
55 | auto st = adaptive_light->Init();
56 | if (st.ok()) {
57 | hap_light->SetAdaptiveLight(std::move(adaptive_light));
58 | }
59 |
60 | mgos::hap::Accessory *pri_acc = accs->front().get();
61 | shelly::hap::LightBulb *light_ref = hap_light.get();
62 | hap_light->set_primary(true);
63 | pri_acc->SetCategory(kHAPAccessoryCategory_Lighting);
64 | pri_acc->AddService(hap_light.get());
65 | pri_acc->SetIdentifyCB(
66 | [light_ref](const HAPAccessoryIdentifyRequest *request UNUSED_ARG) {
67 | light_ref->Identify();
68 | return kHAPError_None;
69 | });
70 |
71 | comps->push_back(std::move(hap_light));
72 | }
73 | } // namespace shelly
74 |
--------------------------------------------------------------------------------
/src/ShellyI3/shelly_init.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) Shelly-HomeKit Contributors
3 | * All rights reserved
4 | *
5 | * Licensed under the Apache License, Version 2.0 (the "License");
6 | * you may not use this file except in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | */
17 |
18 | #include "shelly_hap_input.hpp"
19 | #include "shelly_hap_stateless_switch.hpp"
20 | #include "shelly_main.hpp"
21 | #include "shelly_noisy_input_pin.hpp"
22 | #include "shelly_sys_led_btn.hpp"
23 | #include "shelly_temp_sensor_ntc.hpp"
24 |
25 | namespace shelly {
26 |
27 | // i3 inputs are super noisy and cause interrupt storm.
28 | // Instead we run a frequent hardware timer that smoothes things out.
29 | void CreatePeripherals(std::vector> *inputs,
30 | std::vector> *outputs,
31 | std::vector> *pms UNUSED_ARG,
32 | std::unique_ptr *sys_temp) {
33 | auto *in1 = new NoisyInputPin(1, 14, 1, MGOS_GPIO_PULL_NONE, true);
34 | in1->AddHandler(std::bind(&HandleInputResetSequence, in1, -1, _1, _2));
35 | inputs->emplace_back(in1);
36 | in1->Init();
37 |
38 | auto *in2 = new NoisyInputPin(2, 12, 1, MGOS_GPIO_PULL_NONE, false);
39 | inputs->emplace_back(in2);
40 | in2->Init();
41 |
42 | auto *in3 = new NoisyInputPin(3, 13, 1, MGOS_GPIO_PULL_NONE, false);
43 | inputs->emplace_back(in3);
44 | in3->Init();
45 |
46 | sys_temp->reset(new TempSensorSDNT1608X103F3950(0, 3.3f, 33000.0f));
47 |
48 | InitSysLED(LED_GPIO, LED_ON);
49 | InitSysBtn(BTN_GPIO, BTN_DOWN);
50 | }
51 |
52 | void CreateComponents(std::vector> *comps,
53 | std::vector> *accs,
54 | HAPAccessoryServerRef *svr) {
55 | hap::CreateHAPInput(1, mgos_sys_config_get_in1(), comps, accs, svr);
56 | hap::CreateHAPInput(2, mgos_sys_config_get_in2(), comps, accs, svr);
57 | hap::CreateHAPInput(3, mgos_sys_config_get_in3(), comps, accs, svr);
58 | }
59 |
60 | } // namespace shelly
61 |
--------------------------------------------------------------------------------
/src/ShellyMini1Gen3/shelly_init.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) Shelly-HomeKit Contributors
3 | * All rights reserved
4 | *
5 | * Licensed under the Apache License, Version 2.0 (the "License");
6 | * you may not use this file except in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | */
17 |
18 | #include "shelly_hap_garage_door_opener.hpp"
19 | #include "shelly_hap_input.hpp"
20 | #include "shelly_input_pin.hpp"
21 | #include "shelly_main.hpp"
22 | #include "shelly_sys_led_btn.hpp"
23 | #include "shelly_temp_sensor_ntc.hpp"
24 |
25 | namespace shelly {
26 |
27 | void CreatePeripherals(std::vector> *inputs,
28 | std::vector> *outputs,
29 | std::vector> *pms UNUSED_ARG,
30 | std::unique_ptr *sys_temp) {
31 | outputs->emplace_back(new OutputPin(1, 7, 1));
32 |
33 | auto *in = new InputPin(1, 10, 1, MGOS_GPIO_PULL_NONE, true);
34 | in->AddHandler(std::bind(&HandleInputResetSequence, in, LED_GPIO, _1, _2));
35 | in->Init();
36 | inputs->emplace_back(in);
37 |
38 | // not yet compatible
39 | #ifdef MGOS_HAVE_ADC
40 | sys_temp->reset(new TempSensorSDNT1608X103F3950(3, 3.3f, 10000.0f));
41 | #endif
42 |
43 | InitSysLED(LED_GPIO, LED_ON);
44 | InitSysBtn(BTN_GPIO, BTN_DOWN);
45 | }
46 |
47 | void CreateComponents(std::vector> *comps,
48 | std::vector> *accs,
49 | HAPAccessoryServerRef *svr) {
50 | bool gdo_mode = mgos_sys_config_get_shelly_mode() == (int) Mode::kGarageDoor;
51 | if (gdo_mode) {
52 | hap::CreateHAPGDO(1, FindInput(1), FindInput(2), FindOutput(1),
53 | FindOutput(1), mgos_sys_config_get_gdo1(), comps, accs,
54 | svr, true);
55 | } else {
56 | CreateHAPSwitch(
57 | 1, mgos_sys_config_get_sw1(), mgos_sys_config_get_in1(), comps, accs,
58 | svr, mgos_sys_config_get_sw1_in_mode() != (int) InMode::kDetached);
59 | }
60 | }
61 |
62 | } // namespace shelly
63 |
--------------------------------------------------------------------------------
/src/ShellyMini1PMGen3/shelly_init.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) Shelly-HomeKit Contributors
3 | * All rights reserved
4 | *
5 | * Licensed under the Apache License, Version 2.0 (the "License");
6 | * you may not use this file except in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | */
17 |
18 | #include "shelly_hap_garage_door_opener.hpp"
19 | #include "shelly_hap_input.hpp"
20 | #include "shelly_input_pin.hpp"
21 | #include "shelly_main.hpp"
22 | #include "shelly_pm_bl0942.hpp"
23 | #include "shelly_sys_led_btn.hpp"
24 | #include "shelly_temp_sensor_ntc.hpp"
25 |
26 | namespace shelly {
27 |
28 | void CreatePeripherals(std::vector> *inputs,
29 | std::vector> *outputs,
30 | std::vector> *pms UNUSED_ARG,
31 | std::unique_ptr *sys_temp) {
32 | outputs->emplace_back(new OutputPin(1, 5, 1));
33 |
34 | auto *in = new InputPin(1, 10, 1, MGOS_GPIO_PULL_NONE, true);
35 | in->AddHandler(std::bind(&HandleInputResetSequence, in, LED_GPIO, _1, _2));
36 | in->Init();
37 | inputs->emplace_back(in);
38 |
39 | #ifdef MGOS_HAVE_ADC
40 | sys_temp->reset(new TempSensorSDNT1608X103F3950(3, 3.3f, 10000.0f));
41 | #endif
42 |
43 | struct bl0942_cfg cfg = {
44 | .voltage_scale = (73989 / (1.218 * 4)),
45 | .current_scale = (305978 / (1.218)),
46 | .apower_scale = (3537 / (1.218 * 1.218 * 4)),
47 | .aenergy_scale = ((3537 / (1.218 * 1.218 * 4)) * 3600 / (1638.4 * 256))};
48 |
49 | mgos_config_factory *c = &(mgos_sys_config.factory);
50 | if (c->calib.done) {
51 | mgos_config_scales *g = &c->calib.scales0;
52 | cfg.voltage_scale = g->voltage_scale / 500;
53 | cfg.current_scale = g->current_scale / 2;
54 | cfg.apower_scale = 1e11 / g->apower_scale;
55 | cfg.aenergy_scale = 1e11 / g->aenergy_scale;
56 | }
57 |
58 | std::unique_ptr pm(new BL0942PowerMeter(1, 6, 7, 1, 1, cfg));
59 | // BL0942 GPIO6 TX GPIO7 RX
60 | const Status &st = pm->Init();
61 | if (st.ok()) {
62 | pms->emplace_back(std::move(pm));
63 | } else {
64 | const std::string &s = st.ToString();
65 | LOG(LL_ERROR, ("PM init failed: %s", s.c_str()));
66 | }
67 |
68 | InitSysLED(LED_GPIO, LED_ON);
69 | InitSysBtn(BTN_GPIO, BTN_DOWN);
70 | }
71 |
72 | void CreateComponents(std::vector> *comps,
73 | std::vector> *accs,
74 | HAPAccessoryServerRef *svr) {
75 | bool gdo_mode = mgos_sys_config_get_shelly_mode() == (int) Mode::kGarageDoor;
76 | if (gdo_mode) {
77 | hap::CreateHAPGDO(1, FindInput(1), FindInput(2), FindOutput(1),
78 | FindOutput(1), mgos_sys_config_get_gdo1(), comps, accs,
79 | svr, true);
80 | } else {
81 | CreateHAPSwitch(
82 | 1, mgos_sys_config_get_sw1(), mgos_sys_config_get_in1(), comps, accs,
83 | svr, mgos_sys_config_get_sw1_in_mode() != (int) InMode::kDetached);
84 | }
85 | }
86 |
87 | } // namespace shelly
88 |
--------------------------------------------------------------------------------
/src/ShellyPlug/shelly_init.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) Shelly-HomeKit Contributors
3 | * All rights reserved
4 | *
5 | * Licensed under the Apache License, Version 2.0 (the "License");
6 | * you may not use this file except in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | */
17 |
18 | #include "mgos_gpio.h"
19 |
20 | #include "shelly_main.hpp"
21 | #include "shelly_pm_bl0937.hpp"
22 | #include "shelly_sys_led_btn.hpp"
23 |
24 | namespace shelly {
25 |
26 | void CreatePeripherals(std::vector> *inputs,
27 | std::vector> *outputs,
28 | std::vector> *pms UNUSED_ARG,
29 | std::unique_ptr *sys_temp UNUSED_ARG) {
30 | outputs->emplace_back(new OutputPin(1, 4, 1));
31 | mgos_gpio_setup_output(14, 0); // Red
32 | mgos_gpio_setup_output(16, 0); // Blue
33 | std::unique_ptr pm(
34 | new BL0937PowerMeter(1, 5 /* CF */, -1 /* CF1 */, -1 /* SEL */, 3,
35 | mgos_sys_config_get_bl0937_power_coeff()));
36 | const Status &st = pm->Init();
37 | if (st.ok()) {
38 | pms->emplace_back(std::move(pm));
39 | } else {
40 | const std::string &s = st.ToString();
41 | LOG(LL_ERROR, ("PM init failed: %s", s.c_str()));
42 | }
43 |
44 | InitSysLED(LED_GPIO, LED_ON);
45 | InitSysBtn(BTN_GPIO, BTN_DOWN);
46 | }
47 |
48 | void CreateComponents(std::vector> *comps,
49 | std::vector> *accs,
50 | HAPAccessoryServerRef *svr) {
51 | CreateHAPSwitch(1, mgos_sys_config_get_sw1(), nullptr, comps, accs, svr,
52 | true /* to_pri_acc */);
53 | }
54 |
55 | } // namespace shelly
56 |
--------------------------------------------------------------------------------
/src/ShellyPlugS/shelly_init.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) Shelly-HomeKit Contributors
3 | * All rights reserved
4 | *
5 | * Licensed under the Apache License, Version 2.0 (the "License");
6 | * you may not use this file except in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | */
17 |
18 | #include "shelly_main.hpp"
19 | #include "shelly_output.hpp"
20 | #include "shelly_pm_bl0937.hpp"
21 | #include "shelly_sys_led_btn.hpp"
22 | #include "shelly_temp_sensor_ntc.hpp"
23 |
24 | namespace shelly {
25 |
26 | static OutputPin *s_led_out = nullptr;
27 |
28 | void CreatePeripherals(std::vector> *inputs,
29 | std::vector> *outputs,
30 | std::vector> *pms,
31 | std::unique_ptr *sys_temp) {
32 | outputs->emplace_back(new OutputPin(1, 15, 1));
33 | s_led_out = new OutputPin(99, 0, 0); // Red LED.
34 | std::unique_ptr pm(
35 | new BL0937PowerMeter(1, 5 /* CF */, 14 /* CF1 */, 12 /* SEL */, 2,
36 | mgos_sys_config_get_bl0937_power_coeff()));
37 | const Status &st = pm->Init();
38 | if (st.ok()) {
39 | pms->emplace_back(std::move(pm));
40 | } else {
41 | const std::string &s = st.ToString();
42 | LOG(LL_ERROR, ("PM init failed: %s", s.c_str()));
43 | }
44 | sys_temp->reset(new TempSensorSDNT1608X103F3950(0, 3.3f, 33000.0f));
45 |
46 | InitSysLED(LED_GPIO, LED_ON);
47 | InitSysBtn(BTN_GPIO, BTN_DOWN);
48 | }
49 |
50 | void CreateComponents(std::vector> *comps,
51 | std::vector> *accs,
52 | HAPAccessoryServerRef *svr) {
53 | CreateHAPSwitch(1, mgos_sys_config_get_sw1(), nullptr, comps, accs, svr,
54 | true /* to_pri_acc */, s_led_out);
55 | }
56 |
57 | } // namespace shelly
58 |
--------------------------------------------------------------------------------
/src/ShellyPlus1/shelly_init.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) Shelly-HomeKit Contributors
3 | * All rights reserved
4 | *
5 | * Licensed under the Apache License, Version 2.0 (the "License");
6 | * you may not use this file except in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | */
17 |
18 | #include "shelly_dht_sensor.hpp"
19 | #include "shelly_hap_garage_door_opener.hpp"
20 | #include "shelly_hap_input.hpp"
21 | #include "shelly_input_pin.hpp"
22 | #include "shelly_main.hpp"
23 | #include "shelly_sys_led_btn.hpp"
24 | #include "shelly_temp_sensor_ntc.hpp"
25 | #include "shelly_temp_sensor_ow.hpp"
26 |
27 | namespace shelly {
28 |
29 | static std::unique_ptr s_onewire;
30 | static std::vector> sensors;
31 |
32 | void CreatePeripherals(std::vector> *inputs,
33 | std::vector> *outputs,
34 | std::vector> *pms UNUSED_ARG,
35 | std::unique_ptr *sys_temp) {
36 | outputs->emplace_back(new OutputPin(1, RELAY1_GPIO, 1));
37 | auto *in = new InputPin(1, SWITCH1_GPIO, 1, MGOS_GPIO_PULL_NONE, true);
38 | in->AddHandler(std::bind(&HandleInputResetSequence, in, LED_GPIO, _1, _2));
39 | in->Init();
40 | inputs->emplace_back(in);
41 | sys_temp->reset(new TempSensorSDNT1608X103F3950(ADC_GPIO, 3.3f, 10000.0f));
42 |
43 | int pin_out = ADDON_OUT_GPIO;
44 | int pin_in = ADDON_IN_GPIO;
45 |
46 | if (DetectAddon(pin_in, pin_out)) {
47 | s_onewire.reset(new Onewire(pin_in, pin_out));
48 | sensors = s_onewire->DiscoverAll();
49 | if (sensors.empty()) {
50 | s_onewire.reset();
51 | sensors = DiscoverDHTSensors(pin_in, pin_out);
52 | }
53 |
54 | if (ADDON_DIG_GPIO != -1) {
55 | auto *in2 =
56 | new InputPin(2, ADDON_DIG_GPIO, 0, MGOS_GPIO_PULL_NONE, false);
57 | in2->Init();
58 | inputs->emplace_back(in2);
59 | }
60 |
61 | } else {
62 | RestoreUART();
63 | InitSysLED(LED_GPIO, LED_ON);
64 | }
65 | InitSysBtn(BTN_GPIO, BTN_DOWN);
66 | }
67 |
68 | void CreateComponents(std::vector> *comps,
69 | std::vector> *accs,
70 | HAPAccessoryServerRef *svr) {
71 | bool gdo_mode = mgos_sys_config_get_shelly_mode() == (int) Mode::kGarageDoor;
72 | bool ext_sensor_switch = (FindInput(2) != nullptr);
73 | bool addon_input = !gdo_mode && ext_sensor_switch;
74 | bool single_accessory =
75 | sensors.empty() && !addon_input &&
76 | (mgos_sys_config_get_sw1_in_mode() != (int) InMode::kDetached);
77 | if (gdo_mode) {
78 | hap::CreateHAPGDO(1, FindInput(1), FindInput(2), FindOutput(1),
79 | FindOutput(1), mgos_sys_config_get_gdo1(), comps, accs,
80 | svr, true);
81 | } else {
82 | CreateHAPSwitch(1, mgos_sys_config_get_sw1(), mgos_sys_config_get_in1(),
83 | comps, accs, svr, single_accessory);
84 | }
85 |
86 | if (!sensors.empty()) {
87 | CreateHAPSensors(&sensors, comps, accs, svr);
88 | }
89 | if (addon_input) {
90 | hap::CreateHAPInput(2, mgos_sys_config_get_in2(), comps, accs, svr);
91 | }
92 | }
93 |
94 | } // namespace shelly
95 |
--------------------------------------------------------------------------------
/src/ShellyPlusI4/shelly_init.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) Shelly-HomeKit Contributors
3 | * All rights reserved
4 | *
5 | * Licensed under the Apache License, Version 2.0 (the "License");
6 | * you may not use this file except in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | */
17 |
18 | #include "shelly_dht_sensor.hpp"
19 | #include "shelly_hap_input.hpp"
20 | #include "shelly_hap_stateless_switch.hpp"
21 | #include "shelly_main.hpp"
22 | #include "shelly_noisy_input_pin.hpp"
23 | #include "shelly_sys_led_btn.hpp"
24 | #include "shelly_temp_sensor_ntc.hpp"
25 | #include "shelly_temp_sensor_ow.hpp"
26 |
27 | namespace shelly {
28 |
29 | static std::unique_ptr s_onewire;
30 | static std::vector> sensors;
31 |
32 | void CreatePeripherals(std::vector> *inputs,
33 | std::vector> *outputs UNUSED_ARG,
34 | std::vector> *pms UNUSED_ARG,
35 | std::unique_ptr *sys_temp) {
36 | auto *in1 = new InputPin(1, SWITCH1_GPIO, 1, MGOS_GPIO_PULL_NONE, true);
37 | in1->AddHandler(std::bind(&HandleInputResetSequence, in1, LED_GPIO, _1, _2));
38 | in1->Init();
39 | inputs->emplace_back(in1);
40 |
41 | auto *in2 = new NoisyInputPin(2, SWITCH2_GPIO, 1, MGOS_GPIO_PULL_NONE, false);
42 | in2->Init();
43 | inputs->emplace_back(in2);
44 |
45 | auto *in3 = new NoisyInputPin(3, SWITCH3_GPIO, 1, MGOS_GPIO_PULL_NONE, false);
46 | in3->Init();
47 | inputs->emplace_back(in3);
48 |
49 | auto *in4 = new NoisyInputPin(4, SWITCH4_GPIO, 1, MGOS_GPIO_PULL_NONE, false);
50 | in4->Init();
51 | inputs->emplace_back(in4);
52 |
53 | sys_temp->reset(new TempSensorSDNT1608X103F3950(ADC_GPIO, 3.3f, 10000.0f));
54 |
55 | int pin_out = ADDON_OUT_GPIO;
56 | int pin_in = ADDON_IN_GPIO;
57 |
58 | if (DetectAddon(pin_in, pin_out)) {
59 | s_onewire.reset(new Onewire(pin_in, pin_out));
60 | sensors = s_onewire->DiscoverAll();
61 | if (sensors.empty()) {
62 | s_onewire.reset();
63 | sensors = DiscoverDHTSensors(pin_in, pin_out);
64 | }
65 | } else {
66 | RestoreUART();
67 | InitSysLED(LED_GPIO, LED_ON);
68 | }
69 | InitSysBtn(BTN_GPIO, BTN_DOWN);
70 | }
71 |
72 | void CreateComponents(std::vector> *comps,
73 | std::vector> *accs,
74 | HAPAccessoryServerRef *svr) {
75 | hap::CreateHAPInput(1, mgos_sys_config_get_in1(), comps, accs, svr);
76 | hap::CreateHAPInput(2, mgos_sys_config_get_in2(), comps, accs, svr);
77 | hap::CreateHAPInput(3, mgos_sys_config_get_in3(), comps, accs, svr);
78 | hap::CreateHAPInput(4, mgos_sys_config_get_in4(), comps, accs, svr);
79 |
80 | if (!sensors.empty()) {
81 | CreateHAPSensors(&sensors, comps, accs, svr);
82 | }
83 | }
84 |
85 | } // namespace shelly
86 |
--------------------------------------------------------------------------------
/src/ShellyPlusPlugS/shelly_init.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) Shelly-HomeKit Contributors
3 | * All rights reserved
4 | *
5 | * Licensed under the Apache License, Version 2.0 (the "License");
6 | * you may not use this file except in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | */
17 |
18 | #include "mgos_gpio.h"
19 | #include "shelly_main.hpp"
20 | #include "shelly_output.hpp"
21 | #include "shelly_statusled.hpp"
22 | #include "shelly_sys_led_btn.hpp"
23 | #include "shelly_temp_sensor_ntc.hpp"
24 |
25 | #ifdef UART_TX_GPIO
26 | #include "shelly_pm_bl0942.hpp"
27 | #else
28 | #include "shelly_pm_bl0937.hpp"
29 | #endif
30 |
31 | namespace shelly {
32 |
33 | void CreatePeripherals(std::vector> *inputs,
34 | std::vector> *outputs,
35 | std::vector> *pms,
36 | std::unique_ptr *sys_temp) {
37 | outputs->emplace_back(new OutputPin(1, RELAY_GPIO, 1));
38 |
39 | outputs->emplace_back(new StatusLED(2, NEOPX_GPIO, 2, MGOS_NEOPIXEL_ORDER_GRB,
40 | nullptr, mgos_sys_config_get_led()));
41 | #ifdef NEOPX1_GPIO
42 | outputs->emplace_back(new StatusLED(3, NEOPX1_GPIO, 2,
43 | MGOS_NEOPIXEL_ORDER_GRB, FindOutput(2),
44 | mgos_sys_config_get_led()));
45 | #endif
46 |
47 | #ifndef UART_TX_GPIO
48 | std::unique_ptr pm(
49 | new BL0937PowerMeter(1, 10 /* CF */, 22 /* CF1 */, 19 /* SEL */, 2,
50 | mgos_sys_config_get_bl0937_power_coeff()));
51 | #else
52 |
53 | struct bl0942_cfg cfg = {
54 | .voltage_scale = (73989 / (1.218 * 4)),
55 | .current_scale = (305978 / (1.218)),
56 | .apower_scale = (3537 / (1.218 * 1.218 * 4)),
57 | .aenergy_scale = ((3537 / (1.218 * 1.218 * 4)) * 3600 / (1638.4 * 256))};
58 |
59 | mgos_config_factory *c = &(mgos_sys_config.factory);
60 | if (c->calib.done) {
61 | mgos_config_scales *g = &c->calib.scales0;
62 | cfg.voltage_scale = g->voltage_scale / 500;
63 | cfg.current_scale = g->current_scale / 2;
64 | cfg.apower_scale = 1e11 / g->apower_scale;
65 | cfg.aenergy_scale = 1e11 / g->aenergy_scale;
66 | }
67 |
68 | std::unique_ptr pm(
69 | new BL0942PowerMeter(1, UART_TX_GPIO, UART_RX_GPIO, 1, 1, cfg));
70 | #endif
71 |
72 | const Status &st = pm->Init();
73 | if (st.ok()) {
74 | pms->emplace_back(std::move(pm));
75 | } else {
76 | const std::string &s = st.ToString();
77 | LOG(LL_ERROR, ("PM init failed: %s", s.c_str()));
78 | }
79 | sys_temp->reset(new TempSensorSDNT1608X103F3950(ADC_GPIO, 3.3f, 10000.0f));
80 |
81 | InitSysLED(LED_GPIO, LED_ON);
82 | InitSysBtn(BTN_GPIO, BTN_DOWN);
83 | }
84 |
85 | void CreateComponents(std::vector> *comps,
86 | std::vector> *accs,
87 | HAPAccessoryServerRef *svr) {
88 | CreateHAPSwitch(1, mgos_sys_config_get_sw1(), nullptr, comps, accs, svr,
89 | true /* to_pri_acc */, FindOutput(3));
90 | }
91 |
92 | } // namespace shelly
93 |
--------------------------------------------------------------------------------
/src/ShellyT32/shelly_init.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2020 Deomid "rojer" Ryabkov
3 | * All rights reserved
4 | *
5 | * Licensed under the Apache License, Version 2.0 (the "License");
6 | * you may not use this file except in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | */
17 |
18 | #include "mgos_hap.hpp"
19 | #include "mgos_sys_config.h"
20 |
21 | #include "shelly_input_pin.hpp"
22 | #include "shelly_main.hpp"
23 | #include "shelly_pm.hpp"
24 | #include "shelly_sys_led_btn.hpp"
25 |
26 | namespace shelly {
27 |
28 | void CreatePeripherals(std::vector> *inputs,
29 | std::vector> *outputs,
30 | std::vector> *pms,
31 | std::unique_ptr *sys_temp UNUSED_ARG) {
32 | outputs->emplace_back(new OutputPin(1, 32, 1));
33 | auto *in = new InputPin(1, 34, 0, MGOS_GPIO_PULL_UP, true);
34 | in->AddHandler(std::bind(&HandleInputResetSequence, in, 32, _1, _2));
35 | in->Init();
36 | inputs->emplace_back(in);
37 |
38 | InitSysLED(LED_GPIO, LED_ON);
39 | InitSysBtn(BTN_GPIO, BTN_DOWN);
40 | }
41 |
42 | void CreateComponents(std::vector> *comps,
43 | std::vector> *accs,
44 | HAPAccessoryServerRef *svr) {
45 | CreateHAPSwitch(1, mgos_sys_config_get_sw1(), mgos_sys_config_get_in1(),
46 | comps, accs, svr, true /* to_pri_acc */);
47 | }
48 |
49 | } // namespace shelly
50 |
--------------------------------------------------------------------------------
/src/ShellyU/shelly_init.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) Shelly-HomeKit Contributors
3 | * All rights reserved
4 | *
5 | * Licensed under the Apache License, Version 2.0 (the "License");
6 | * you may not use this file except in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | */
17 |
18 | #include
19 |
20 | #include "mgos_hap.h"
21 | #include "mgos_rpc.h"
22 | #include "mgos_sys_config.h"
23 |
24 | #include "shelly_hap_input.hpp"
25 | #include "shelly_hap_temperature_sensor.hpp"
26 | #include "shelly_input_pin.hpp"
27 | #include "shelly_main.hpp"
28 | #include "shelly_mock.hpp"
29 | #include "shelly_output.hpp"
30 |
31 | namespace shelly {
32 |
33 | static std::vector> sensors;
34 |
35 | void CreatePeripherals(std::vector> *inputs,
36 | std::vector> *outputs,
37 | std::vector> *pms,
38 | std::unique_ptr *sys_temp) {
39 | auto *in1 = new InputPin(1, 12, 1, MGOS_GPIO_PULL_NONE, true);
40 | in1->Init();
41 | inputs->emplace_back(in1);
42 |
43 | auto *in2 = new InputPin(2, 3, 0, MGOS_GPIO_PULL_NONE, false);
44 | in2->Init();
45 | inputs->emplace_back(in2);
46 |
47 | outputs->emplace_back(new OutputPin(1, 34, 1));
48 |
49 | g_mock_sys_temp_sensor = new MockTempSensor(33);
50 | sys_temp->reset(g_mock_sys_temp_sensor);
51 |
52 | MockRPCInit();
53 | (void) pms;
54 | }
55 |
56 | void CreateComponents(std::vector> *comps,
57 | std::vector> *accs,
58 | HAPAccessoryServerRef *svr) {
59 | CreateHAPSwitch(1, mgos_sys_config_get_sw1(), mgos_sys_config_get_in1(),
60 | comps, accs, svr, false /* to_pri_acc */,
61 | nullptr /* led_out */);
62 |
63 | for (int i = 0; i < 2; i++) {
64 | std::unique_ptr temp(new MockTempSensor(25.125 + i));
65 | sensors.push_back(std::move(temp));
66 | }
67 |
68 | bool ext_switch_detected = false; // can be set for testing purposes
69 |
70 | if (ext_switch_detected) {
71 | hap::CreateHAPInput(2, mgos_sys_config_get_in2(), comps, accs, svr);
72 | } else {
73 | if (!sensors.empty()) {
74 | CreateHAPSensors(&sensors, comps, accs, svr);
75 | }
76 | }
77 | }
78 |
79 | } // namespace shelly
80 |
--------------------------------------------------------------------------------
/src/ShellyU25/shelly_init.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) Shelly-HomeKit Contributors
3 | * All rights reserved
4 | *
5 | * Licensed under the Apache License, Version 2.0 (the "License");
6 | * you may not use this file except in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | */
17 |
18 | #include
19 |
20 | #include "mgos_sys_config.h"
21 |
22 | #include "shelly_input_pin.hpp"
23 | #include "shelly_main.hpp"
24 | #include "shelly_mock.hpp"
25 | #include "shelly_output.hpp"
26 |
27 | namespace shelly {
28 |
29 | void CreatePeripherals(std::vector> *inputs,
30 | std::vector> *outputs,
31 | std::vector> *pms,
32 | std::unique_ptr *sys_temp) {
33 | std::unique_ptr in1(new InputPin(1, 12, 1, MGOS_GPIO_PULL_NONE, true));
34 | in1->Init();
35 | inputs->emplace_back(std::move(in1));
36 | std::unique_ptr in2(new InputPin(2, 13, 1, MGOS_GPIO_PULL_NONE, true));
37 | in2->Init();
38 | inputs->emplace_back(std::move(in2));
39 |
40 | outputs->emplace_back(new OutputPin(1, 34, 1));
41 | outputs->emplace_back(new OutputPin(2, 35, 1));
42 |
43 | std::unique_ptr pm1(new MockPowerMeter(1));
44 | pm1->Init();
45 | g_mock_pms.push_back(pm1.get());
46 | pms->emplace_back(std::move(pm1));
47 | std::unique_ptr pm2(new MockPowerMeter(2));
48 | pm2->Init();
49 | g_mock_pms.push_back(pm2.get());
50 | pms->emplace_back(std::move(pm2));
51 |
52 | g_mock_sys_temp_sensor = new MockTempSensor(33);
53 | sys_temp->reset(g_mock_sys_temp_sensor);
54 |
55 | MockRPCInit();
56 | }
57 |
58 | } // namespace shelly
59 |
--------------------------------------------------------------------------------
/src/ShellyUNI/shelly_init.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) Shelly-HomeKit Contributors
3 | * All rights reserved
4 | *
5 | * Licensed under the Apache License, Version 2.0 (the "License");
6 | * you may not use this file except in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | */
17 |
18 | #include
19 |
20 | #include "shelly_dht_sensor.hpp"
21 | #include "shelly_hap_garage_door_opener.hpp"
22 | #include "shelly_hap_input.hpp"
23 | #include "shelly_hap_window_covering.hpp"
24 | #include "shelly_main.hpp"
25 | #include "shelly_noisy_input_pin.hpp"
26 | #include "shelly_sys_led_btn.hpp"
27 | #include "shelly_temp_sensor_ow.hpp"
28 |
29 | namespace shelly {
30 |
31 | static std::unique_ptr s_onewire;
32 | static std::vector> sensors;
33 |
34 | void CreatePeripherals(std::vector> *inputs,
35 | std::vector> *outputs,
36 | std::vector> *pms,
37 | std::unique_ptr *sys_temp) {
38 | outputs->emplace_back(new OutputPin(1, RELAY1_GPIO, 1));
39 | outputs->emplace_back(new OutputPin(2, RELAY2_GPIO, 1));
40 | auto *in1 = new NoisyInputPin(1, SWITCH1_GPIO, 1, MGOS_GPIO_PULL_NONE, true);
41 | in1->AddHandler(std::bind(&HandleInputResetSequence, in1, LED_GPIO, _1, _2));
42 | in1->Init();
43 | inputs->emplace_back(in1);
44 | auto *in2 = new NoisyInputPin(2, SWITCH2_GPIO, 1, MGOS_GPIO_PULL_NONE, false);
45 | in2->Init();
46 | inputs->emplace_back(in2);
47 |
48 | s_onewire.reset(new Onewire(SENSOR_GPIO, SENSOR_GPIO));
49 | sensors = s_onewire->DiscoverAll();
50 | if (sensors.empty()) {
51 | s_onewire.reset();
52 | sensors = DiscoverDHTSensors(SENSOR_GPIO, SENSOR_GPIO);
53 | }
54 |
55 | InitSysLED(LED_GPIO, LED_ON);
56 | InitSysBtn(BTN_GPIO, BTN_DOWN);
57 | }
58 |
59 | void CreateComponents(std::vector> *comps,
60 | std::vector> *accs,
61 | HAPAccessoryServerRef *svr) {
62 | bool gdo_mode = mgos_sys_config_get_shelly_mode() == (int) Mode::kGarageDoor;
63 |
64 | if (gdo_mode) {
65 | hap::CreateHAPGDO(1, FindInput(1), FindInput(2), FindOutput(1),
66 | FindOutput(2), mgos_sys_config_get_gdo1(), comps, accs,
67 | svr, true);
68 | } else {
69 | CreateHAPSwitch(1, mgos_sys_config_get_sw1(), mgos_sys_config_get_in1(),
70 | comps, accs, svr, false /* to_pri_acc */);
71 | CreateHAPSwitch(2, mgos_sys_config_get_sw2(), mgos_sys_config_get_in2(),
72 | comps, accs, svr, false /* to_pri_acc */);
73 | }
74 |
75 | if (!sensors.empty()) {
76 | CreateHAPSensors(&sensors, comps, accs, svr);
77 | }
78 | }
79 |
80 | } // namespace shelly
81 |
--------------------------------------------------------------------------------
/src/ShellyVintage/shelly_init.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) Shelly-HomeKit Contributors
3 | * All rights reserved
4 | *
5 | * Licensed under the Apache License, Version 2.0 (the "License");
6 | * you may not use this file except in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | */
17 |
18 | #include "shelly_hap_input.hpp"
19 | #include "shelly_hap_light_bulb.hpp"
20 | #include "shelly_input_pin.hpp"
21 | #include "shelly_light_bulb_controller.hpp"
22 | #include "shelly_main.hpp"
23 | #include "shelly_white_controller.hpp"
24 |
25 | namespace shelly {
26 |
27 | void CreatePeripherals(UNUSED_ARG std::vector> *inputs,
28 | std::vector> *outputs,
29 | UNUSED_ARG std::vector> *pms,
30 | UNUSED_ARG std::unique_ptr *sys_temp) {
31 | outputs->emplace_back(new OutputPin(1, 4, 1));
32 | }
33 |
34 | void CreateComponents(std::vector> *comps,
35 | std::vector> *accs,
36 | HAPAccessoryServerRef *svr) {
37 | std::unique_ptr lightbulb_controller;
38 | std::unique_ptr hap_light;
39 | auto *lb_cfg = (struct mgos_config_lb *) mgos_sys_config_get_lb1();
40 |
41 | lightbulb_controller.reset(new WhiteController(lb_cfg, FindOutput(1)));
42 |
43 | hap_light.reset(new hap::LightBulb(
44 | 1, nullptr, std::move(lightbulb_controller), lb_cfg, false));
45 |
46 | if (hap_light == nullptr || !hap_light->Init().ok()) {
47 | return;
48 | }
49 |
50 | mgos::hap::Accessory *pri_acc = accs->front().get();
51 | shelly::hap::LightBulb *light_ref = hap_light.get();
52 | hap_light->set_primary(true);
53 | pri_acc->SetCategory(kHAPAccessoryCategory_Lighting);
54 | pri_acc->AddService(hap_light.get());
55 | pri_acc->SetIdentifyCB(
56 | [light_ref](const HAPAccessoryIdentifyRequest *request UNUSED_ARG) {
57 | light_ref->Identify();
58 | return kHAPError_None;
59 | });
60 |
61 | comps->push_back(std::move(hap_light));
62 | }
63 |
64 | } // namespace shelly
65 |
--------------------------------------------------------------------------------
/src/mock/pwm/mgos_pwm.c:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) Shelly-HomeKit Contributors
3 | * All rights reserved
4 | *
5 | * Licensed under the Apache License, Version 2.0 (the "License");
6 | * you may not use this file except in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | */
17 |
18 | // TODO: move over to https://github.com/mongoose-os-libs/pwm
19 |
20 | #include "mgos_pwm.h"
21 |
22 | bool mgos_pwm_set(int pin, int freq, float duty) {
23 | return true;
24 | (void) pin;
25 | (void) freq;
26 | (void) duty;
27 | };
28 |
--------------------------------------------------------------------------------
/src/mock/pwm/mgos_pwm.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2014-2018 Cesanta Software Limited
3 | * All rights reserved
4 | *
5 | * Licensed under the Apache License, Version 2.0 (the ""License"");
6 | * you may not use this file except in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an ""AS IS"" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | */
17 |
18 | #ifndef CS_MOS_LIBS_PWM_SRC_MGOS_PWM_H_
19 | #define CS_MOS_LIBS_PWM_SRC_MGOS_PWM_H_
20 |
21 | #include
22 |
23 | #ifdef __cplusplus
24 | extern "C" {
25 | #endif /* __cplusplus */
26 |
27 | /*
28 | *
29 | * Set and control the PWM.
30 | *
31 | * Params:
32 | * pin: GPIO number.
33 | * freq: Frequency, in Hz. 0 disables PWM on the pin.
34 | * duty: Specifies which fraction of the cycle is spent in "1" state:
35 | * 0 is always off, 0.5 is a square wave, 1 is always on.
36 | * Return:
37 | * true - SUCCESS, false - FAIL.
38 | *
39 | * Note:
40 | * On esp32 we use 8 channels and 4 timers.
41 | * Each `mgos_set_pwm` call with new pin number assigns a new channel.
42 | * If we already have timer running at the specified frequency,
43 | * we use it instead of assigning a new one.
44 | */
45 | bool mgos_pwm_set(int pin, int freq, float duty);
46 |
47 | #ifdef __cplusplus
48 | }
49 | #endif /* __cplusplus */
50 |
51 | #endif /* CS_MOS_LIBS_PWM_SRC_MGOS_PWM_H_ */
52 |
--------------------------------------------------------------------------------
/src/mock/shelly_mock.hpp:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) Shelly-HomeKit Contributors
3 | * All rights reserved
4 | *
5 | * Licensed under the Apache License, Version 2.0 (the "License");
6 | * you may not use this file except in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | */
17 |
18 | #pragma once
19 |
20 | #include
21 |
22 | #include "shelly_mock_pm.hpp"
23 | #include "shelly_mock_temp_sensor.hpp"
24 |
25 | namespace shelly {
26 |
27 | extern std::vector g_mock_pms;
28 | extern MockTempSensor *g_mock_sys_temp_sensor;
29 |
30 | void MockRPCInit();
31 |
32 | } // namespace shelly
33 |
--------------------------------------------------------------------------------
/src/mock/shelly_mock_pm.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) Shelly-HomeKit Contributors
3 | * All rights reserved
4 | *
5 | * Licensed under the Apache License, Version 2.0 (the "License");
6 | * you may not use this file except in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | */
17 |
18 | #include "shelly_mock_pm.hpp"
19 |
20 | namespace shelly {
21 |
22 | MockPowerMeter::MockPowerMeter(int id)
23 | : PowerMeter(id),
24 | meas_timer_(std::bind(&MockPowerMeter::MeasureTimerCB, this)) {
25 | }
26 |
27 | MockPowerMeter::~MockPowerMeter() {
28 | }
29 |
30 | Status MockPowerMeter::Init() {
31 | meas_timer_.Reset(1000, MGOS_TIMER_REPEAT);
32 | return Status::OK();
33 | }
34 |
35 | StatusOr MockPowerMeter::GetPowerW() {
36 | return apa_;
37 | }
38 |
39 | StatusOr MockPowerMeter::GetEnergyWH() {
40 | return aea_;
41 | }
42 |
43 | void MockPowerMeter::SetPowerW(float w) {
44 | LOG(LL_INFO, ("PM %d W %.2f -> %.2f", id(), apa_, w));
45 | apa_ = w;
46 | }
47 |
48 | void MockPowerMeter::SetEnergyWH(float wh) {
49 | LOG(LL_INFO, ("PM %d WH %.2f -> %.2f", id(), aea_, wh));
50 | aea_ = wh;
51 | }
52 |
53 | void MockPowerMeter::MeasureTimerCB() {
54 | aea_ += (apa_ / 3600);
55 | }
56 |
57 | } // namespace shelly
58 |
--------------------------------------------------------------------------------
/src/mock/shelly_mock_pm.hpp:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) Shelly-HomeKit Contributors
3 | * All rights reserved
4 | *
5 | * Licensed under the Apache License, Version 2.0 (the "License");
6 | * you may not use this file except in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | */
17 |
18 | #pragma once
19 |
20 | #include "shelly_pm.hpp"
21 |
22 | #include "mgos_timers.hpp"
23 |
24 | namespace shelly {
25 |
26 | class MockPowerMeter : public PowerMeter {
27 | public:
28 | explicit MockPowerMeter(int id);
29 | virtual ~MockPowerMeter();
30 |
31 | // PowerMeter interface impl.
32 | Status Init() override;
33 | StatusOr GetPowerW() override;
34 | StatusOr GetEnergyWH() override;
35 |
36 | void SetPowerW(float w);
37 | void SetEnergyWH(float wh);
38 |
39 | private:
40 | void MeasureTimerCB();
41 |
42 | float apa_ = 0;
43 | float aea_ = 0;
44 | mgos::Timer meas_timer_;
45 | };
46 |
47 | } // namespace shelly
48 |
--------------------------------------------------------------------------------
/src/mock/shelly_mock_rpc_service.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) Shelly-HomeKit Contributors
3 | * All rights reserved
4 | *
5 | * Licensed under the Apache License, Version 2.0 (the "License");
6 | * you may not use this file except in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | */
17 |
18 | #include "shelly_mock.hpp"
19 |
20 | #include
21 |
22 | #include "mgos_rpc.h"
23 |
24 | #include "shelly_mock_pm.hpp"
25 | #include "shelly_mock_temp_sensor.hpp"
26 |
27 | namespace shelly {
28 |
29 | std::vector g_mock_pms;
30 | MockTempSensor *g_mock_sys_temp_sensor = nullptr;
31 |
32 | static void MockSetSysTempHandler(struct mg_rpc_request_info *ri, void *cb_arg,
33 | struct mg_rpc_frame_info *fi,
34 | struct mg_str args) {
35 | float temp = NAN;
36 | json_scanf(args.p, args.len, ri->args_fmt, &temp);
37 | g_mock_sys_temp_sensor->SetValue(temp);
38 | mg_rpc_send_responsef(ri, nullptr);
39 | (void) fi;
40 | (void) cb_arg;
41 | }
42 |
43 | static void MockSetPM(struct mg_rpc_request_info *ri, void *cb_arg,
44 | struct mg_rpc_frame_info *fi, struct mg_str args) {
45 | int id = -1;
46 | float w = NAN, wh = NAN;
47 | json_scanf(args.p, args.len, ri->args_fmt, &id, &w, &wh);
48 | if (id < 0) {
49 | mg_rpc_send_errorf(ri, 400, "%s is required", "id");
50 | return;
51 | }
52 | if (std::isnan(w) && std::isnan(wh)) {
53 | mg_rpc_send_errorf(ri, 400, "%s is required", "w or wh");
54 | return;
55 | }
56 | for (auto *pm : g_mock_pms) {
57 | if (pm->id() == id) {
58 | if (!std::isnan(w)) pm->SetPowerW(w);
59 | if (!std::isnan(wh)) pm->SetEnergyWH(wh);
60 | mg_rpc_send_responsef(ri, nullptr);
61 | return;
62 | }
63 | }
64 | mg_rpc_send_errorf(ri, 404, "pm %d not found", id);
65 | (void) fi;
66 | (void) cb_arg;
67 | }
68 |
69 | void MockRPCInit() {
70 | mg_rpc_add_handler(mgos_rpc_get_global(), "Shelly.Mock.SetSysTemp",
71 | "{temp: %f}", MockSetSysTempHandler, nullptr);
72 | mg_rpc_add_handler(mgos_rpc_get_global(), "Shelly.Mock.SetPM",
73 | "{id: %d, w: %f, wh: %f}", MockSetPM, nullptr);
74 | }
75 |
76 | } // namespace shelly
77 |
--------------------------------------------------------------------------------
/src/mock/shelly_mock_temp_sensor.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) Shelly-HomeKit Contributors
3 | * All rights reserved
4 | *
5 | * Licensed under the Apache License, Version 2.0 (the "License");
6 | * you may not use this file except in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | */
17 |
18 | #include "shelly_mock_temp_sensor.hpp"
19 |
20 | #include "shelly_common.hpp"
21 |
22 | #include
23 |
24 | namespace shelly {
25 |
26 | MockTempSensor::MockTempSensor(float initial_value) : value_(initial_value) {
27 | }
28 |
29 | MockTempSensor::~MockTempSensor() {
30 | }
31 |
32 | Status MockTempSensor::Init() {
33 | return Status::OK();
34 | }
35 |
36 | StatusOr MockTempSensor::GetTemperature() {
37 | if (std::isnan(value_)) {
38 | return mgos::Status(STATUS_UNAVAILABLE, "failed");
39 | }
40 | return value_;
41 | }
42 |
43 | void MockTempSensor::SetValue(float new_value) {
44 | value_ = new_value;
45 | }
46 |
47 | } // namespace shelly
48 |
--------------------------------------------------------------------------------
/src/mock/shelly_mock_temp_sensor.hpp:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) Shelly-HomeKit Contributors
3 | * All rights reserved
4 | *
5 | * Licensed under the Apache License, Version 2.0 (the "License");
6 | * you may not use this file except in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | */
17 |
18 | #pragma once
19 |
20 | #include "shelly_temp_sensor.hpp"
21 |
22 | namespace shelly {
23 |
24 | class MockTempSensor : public TempSensor {
25 | public:
26 | MockTempSensor(float initial_value);
27 | virtual ~MockTempSensor();
28 |
29 | Status Init() override;
30 | StatusOr GetTemperature() override;
31 |
32 | void SetValue(float new_value);
33 |
34 | private:
35 | float value_;
36 | };
37 |
38 | } // namespace shelly
39 |
--------------------------------------------------------------------------------
/src/mock/wifi_config/shelly_wifi_config_impl.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) Shelly-HomeKit Contributors
3 | * All rights reserved
4 | *
5 | * Licensed under the Apache License, Version 2.0 (the "License");
6 | * you may not use this file except in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | */
17 |
18 | #include "shelly_wifi_config.hpp"
19 |
20 | #include "mgos.hpp"
21 |
22 | namespace shelly {
23 |
24 | static WifiConfig s_cfg;
25 |
26 | WifiConfig GetWifiConfig() {
27 | return s_cfg;
28 | }
29 |
30 | Status SetWifiConfig(const WifiConfig &cfg) {
31 | std::string cs = cfg.ToJSON();
32 | LOG(LL_INFO, ("Set wifi config to: %s", cs.c_str()));
33 | s_cfg = cfg;
34 | return Status::OK();
35 | }
36 |
37 | void ResetWifiConfig() {
38 | s_cfg = WifiConfig();
39 | }
40 |
41 | WifiInfo GetWifiInfo() {
42 | WifiInfo empty;
43 | return empty;
44 | }
45 |
46 | void ReportClientRequest(const std::string &client_addr) {
47 | (void) client_addr;
48 | }
49 |
50 | void InitWifiConfigManager() {
51 | }
52 |
53 | void StartWifiConfigManager() {
54 | }
55 |
56 | std::string GetMACAddr(bool sta UNUSED_ARG, bool delims) {
57 | uint8_t mac[6];
58 | device_get_mac_address(mac);
59 | return FormatMACAddr(mac, delims);
60 | }
61 |
62 | } // namespace shelly
63 |
--------------------------------------------------------------------------------
/src/shelly_cct_controller.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) Shelly-HomeKit Contributors
3 | * All rights reserved
4 | *
5 | * Licensed under the Apache License, Version 2.0 (the "License");
6 | * you may not use this file except in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | */
17 |
18 | #include "shelly_cct_controller.hpp"
19 |
20 | #include "mgos.hpp"
21 | #include "mgos_hap_chars.hpp"
22 |
23 | namespace shelly {
24 |
25 | CCTController::CCTController(struct mgos_config_lb *cfg, Output *out_cw,
26 | Output *out_ww)
27 | : LightBulbController(cfg), out_ww_(out_ww), out_cw_(out_cw) {
28 | }
29 |
30 | CCTController::~CCTController() {
31 | }
32 |
33 | void CCTController::ReportTransition(const StateCCT &next,
34 | const StateCCT &prev) {
35 | LOG(LL_INFO, ("Output 1: %.2f => %.2f", prev.ww, next.ww));
36 | LOG(LL_INFO, ("Output 2: %.2f => %.2f", prev.cw, next.cw));
37 | }
38 |
39 | void CCTController::UpdatePWM(const StateCCT &state) {
40 | out_ww_->SetStatePWM(state.ww, "transition");
41 | out_cw_->SetStatePWM(state.cw, "transition");
42 | }
43 |
44 | StateCCT CCTController::ConfigToState(const struct mgos_config_lb &cfg) const {
45 | StateCCT state{};
46 |
47 | if (!cfg.state) return state;
48 |
49 | float v = cfg.brightness / 100.0f;
50 | float temp = cfg.color_temperature;
51 |
52 | // brightness and color temperature [mired] to cw, ww values
53 | // uses additive mixing, so at middle temp it is 50/50
54 | int temp_max = 400;
55 | int temp_min = 50;
56 | temp -= temp_min;
57 | temp /= (temp_max - temp_min);
58 | state.ww = temp * v;
59 | state.cw = (1.0f - temp) * v;
60 | return state;
61 | }
62 |
63 | std::string StateCCT::ToString() const {
64 | return mgos::SPrintf("[ww=%.2f cw=%.2f]", ww, cw);
65 | }
66 |
67 | } // namespace shelly
68 |
--------------------------------------------------------------------------------
/src/shelly_cct_controller.hpp:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) Shelly-HomeKit Contributors
3 | * All rights reserved
4 | *
5 | * Licensed under the Apache License, Version 2.0 (the "License");
6 | * you may not use this file except in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | */
17 |
18 | #pragma once
19 |
20 | #include "mgos.hpp"
21 | #include "mgos_hap_chars.hpp"
22 | #include "mgos_timers.hpp"
23 | #include "shelly_light_bulb_controller.hpp"
24 | #include "shelly_output.hpp"
25 |
26 | namespace shelly {
27 |
28 | struct StateCCT {
29 | float ww;
30 | float cw;
31 |
32 | StateCCT operator+(const StateCCT &other) const {
33 | return {
34 | .ww = ww + other.ww,
35 | .cw = cw + other.cw,
36 | };
37 | }
38 |
39 | StateCCT operator*(float a) const {
40 | return {
41 | .ww = a * ww,
42 | .cw = a * cw,
43 | };
44 | }
45 |
46 | std::string ToString() const;
47 | };
48 |
49 | class CCTController : public LightBulbController {
50 | public:
51 | CCTController(struct mgos_config_lb *cfg, Output *out_ww, Output *out_cw);
52 | CCTController(const CCTController &other) = delete;
53 | ~CCTController();
54 |
55 | BulbType Type() final {
56 | return BulbType::kCCT;
57 | }
58 |
59 | private:
60 | Output *const out_ww_, *const out_cw_;
61 |
62 | StateCCT ConfigToState(const struct mgos_config_lb &cfg) const final;
63 | void ReportTransition(const StateCCT &next, const StateCCT &prev) final;
64 | void UpdatePWM(const StateCCT &state) final;
65 | };
66 | } // namespace shelly
67 |
--------------------------------------------------------------------------------
/src/shelly_component.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) Shelly-HomeKit Contributors
3 | * All rights reserved
4 | *
5 | * Licensed under the Apache License, Version 2.0 (the "License");
6 | * you may not use this file except in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | */
17 |
18 | #include "shelly_component.hpp"
19 |
20 | namespace shelly {
21 |
22 | Component::Component(int id) : id_(id) {
23 | }
24 |
25 | Component::~Component() {
26 | }
27 |
28 | int Component::id() const {
29 | return id_;
30 | }
31 |
32 | void Component::Identify() {
33 | LOG(LL_INFO, ("== Identify %d %d %s", id(), (int) type(), name().c_str()));
34 | }
35 |
36 | bool Component::IsIdle() {
37 | return true;
38 | }
39 |
40 | } // namespace shelly
41 |
--------------------------------------------------------------------------------
/src/shelly_component.hpp:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) Shelly-HomeKit Contributors
3 | * All rights reserved
4 | *
5 | * Licensed under the Apache License, Version 2.0 (the "License");
6 | * you may not use this file except in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | */
17 |
18 | #pragma once
19 |
20 | #include "shelly_common.hpp"
21 |
22 | namespace shelly {
23 |
24 | class Component {
25 | public:
26 | // NB: Keep in sync with Component_Type in JS.
27 | enum class Type {
28 | kSwitch = 0,
29 | kOutlet = 1,
30 | kLock = 2,
31 | kStatelessSwitch = 3,
32 | kWindowCovering = 4,
33 | kGarageDoorOpener = 5,
34 | kDisabledInput = 6,
35 | kMotionSensor = 7,
36 | kOccupancySensor = 8,
37 | kContactSensor = 9,
38 | kDoorbell = 10,
39 | kLightBulb = 11,
40 | kTemperatureSensor = 12,
41 | kLeakSensor = 13,
42 | kSmokeSensor = 14,
43 | kCarbonMonoxideSensor = 15,
44 | kCarbonDioxideSensor = 16,
45 | kMax,
46 | };
47 |
48 | explicit Component(int id);
49 | virtual ~Component();
50 |
51 | int id() const;
52 |
53 | // Complex initialization after construction.
54 | virtual Status Init() = 0;
55 | virtual Type type() const = 0;
56 | virtual std::string name() const = 0;
57 |
58 | // Short status snippet string.
59 | virtual StatusOr GetInfo() const = 0;
60 | // Full JSON status for UI.
61 | virtual StatusOr GetInfoJSON() const = 0;
62 | // Set configuration from UI.
63 | virtual Status SetConfig(const std::string &config_json,
64 | bool *restart_required) = 0;
65 | // Set state from UI.
66 | virtual Status SetState(const std::string &state_json) = 0;
67 | // Do something to identify this component to the user.
68 | // Default is to print a log message, which is to say - not much.
69 | virtual void Identify();
70 |
71 | // Is there any activity going on?
72 | // If true is returned, it means it's ok to destroy the component.
73 | // False should be returned if there is any user-visible activity,
74 | // like curtain moving.
75 | // Default implementation always returns true.
76 | virtual bool IsIdle();
77 |
78 | private:
79 | const int id_;
80 |
81 | Component(const Component &other) = delete;
82 | };
83 |
84 | } // namespace shelly
85 |
--------------------------------------------------------------------------------
/src/shelly_debug.hpp:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) Shelly-HomeKit Contributors
3 | * All rights reserved
4 | *
5 | * Licensed under the Apache License, Version 2.0 (the "License");
6 | * you may not use this file except in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | */
17 |
18 | #include
19 |
20 | #include "HAP.h"
21 |
22 | namespace shelly {
23 |
24 | void GetDebugInfo(std::string *out);
25 |
26 | void SetDebugEnable(bool debug_en);
27 |
28 | bool DebugInit(HAPAccessoryServerRef *svr, HAPPlatformKeyValueStoreRef kvs,
29 | HAPPlatformTCPStreamManagerRef tcpm);
30 |
31 | } // namespace shelly
32 |
--------------------------------------------------------------------------------
/src/shelly_hap_carbon_dioxide_sensor.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) Shelly-HomeKit Contributors
3 | * All rights reserved
4 | *
5 | * Licensed under the Apache License, Version 2.0 (the "License");
6 | * you may not use this file except in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | */
17 |
18 | #include "shelly_hap_carbon_dioxide_sensor.hpp"
19 |
20 | namespace shelly {
21 | namespace hap {
22 |
23 | CarbonDioxideSensor::CarbonDioxideSensor(int id, Input *in,
24 | struct mgos_config_in_sensor *cfg)
25 | : SensorBase(id, in, cfg, SHELLY_HAP_IID_BASE_CARBON_DIOXIDE_SENSOR,
26 | &kHAPServiceType_CarbonDioxideSensor,
27 | kHAPServiceDebugDescription_CarbonDioxideSensor) {
28 | }
29 |
30 | CarbonDioxideSensor::~CarbonDioxideSensor() {
31 | }
32 |
33 | Component::Type CarbonDioxideSensor::type() const {
34 | return Type::kCarbonDioxideSensor;
35 | }
36 |
37 | Status CarbonDioxideSensor::Init() {
38 | const Status &st = SensorBase::Init();
39 | if (!st.ok()) return st;
40 | AddChar(new mgos::hap::UInt8Characteristic(
41 | svc_.iid + 2, &kHAPCharacteristicType_CarbonDioxideDetected, 0, 1, 1,
42 | std::bind(&mgos::hap::ReadUInt8, _1, _2, _3, &state_),
43 | true /* supports_notification */, nullptr /* write_handler */,
44 | kHAPCharacteristicDebugDescription_CarbonDioxideDetected));
45 | return Status::OK();
46 | }
47 |
48 | } // namespace hap
49 | } // namespace shelly
50 |
--------------------------------------------------------------------------------
/src/shelly_hap_carbon_dioxide_sensor.hpp:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) Shelly-HomeKit Contributors
3 | * All rights reserved
4 | *
5 | * Licensed under the Apache License, Version 2.0 (the "License");
6 | * you may not use this file except in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | */
17 |
18 | #pragma once
19 |
20 | #include "shelly_hap_sensor_base.hpp"
21 |
22 | namespace shelly {
23 | namespace hap {
24 |
25 | class CarbonDioxideSensor : public SensorBase {
26 | public:
27 | CarbonDioxideSensor(int id, Input *in, struct mgos_config_in_sensor *cfg);
28 | virtual ~CarbonDioxideSensor();
29 |
30 | // Component interface impl.
31 | Status Init() override;
32 | virtual Type type() const override;
33 | };
34 |
35 | } // namespace hap
36 | } // namespace shelly
37 |
--------------------------------------------------------------------------------
/src/shelly_hap_carbon_monoxide_sensor.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) Shelly-HomeKit Contributors
3 | * All rights reserved
4 | *
5 | * Licensed under the Apache License, Version 2.0 (the "License");
6 | * you may not use this file except in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | */
17 |
18 | #include "shelly_hap_carbon_monoxide_sensor.hpp"
19 |
20 | namespace shelly {
21 | namespace hap {
22 |
23 | CarbonMonoxideSensor::CarbonMonoxideSensor(int id, Input *in,
24 | struct mgos_config_in_sensor *cfg)
25 | : SensorBase(id, in, cfg, SHELLY_HAP_IID_BASE_CARBON_MONOXIDE_SENSOR,
26 | &kHAPServiceType_CarbonMonoxideSensor,
27 | kHAPServiceDebugDescription_CarbonMonoxideSensor) {
28 | }
29 |
30 | CarbonMonoxideSensor::~CarbonMonoxideSensor() {
31 | }
32 |
33 | Component::Type CarbonMonoxideSensor::type() const {
34 | return Type::kCarbonMonoxideSensor;
35 | }
36 |
37 | Status CarbonMonoxideSensor::Init() {
38 | const Status &st = SensorBase::Init();
39 | if (!st.ok()) return st;
40 | AddChar(new mgos::hap::UInt8Characteristic(
41 | svc_.iid + 2, &kHAPCharacteristicType_CarbonMonoxideDetected, 0, 1, 1,
42 | std::bind(&mgos::hap::ReadUInt8, _1, _2, _3, &state_),
43 | true /* supports_notification */, nullptr /* write_handler */,
44 | kHAPCharacteristicDebugDescription_CarbonMonoxideDetected));
45 | return Status::OK();
46 | }
47 |
48 | } // namespace hap
49 | } // namespace shelly
50 |
--------------------------------------------------------------------------------
/src/shelly_hap_carbon_monoxide_sensor.hpp:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) Shelly-HomeKit Contributors
3 | * All rights reserved
4 | *
5 | * Licensed under the Apache License, Version 2.0 (the "License");
6 | * you may not use this file except in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | */
17 |
18 | #pragma once
19 |
20 | #include "shelly_hap_sensor_base.hpp"
21 |
22 | namespace shelly {
23 | namespace hap {
24 |
25 | class CarbonMonoxideSensor : public SensorBase {
26 | public:
27 | CarbonMonoxideSensor(int id, Input *in, struct mgos_config_in_sensor *cfg);
28 | virtual ~CarbonMonoxideSensor();
29 |
30 | // Component interface impl.
31 | Status Init() override;
32 | virtual Type type() const override;
33 | };
34 |
35 | } // namespace hap
36 | } // namespace shelly
37 |
--------------------------------------------------------------------------------
/src/shelly_hap_contact_sensor.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) Shelly-HomeKit Contributors
3 | * All rights reserved
4 | *
5 | * Licensed under the Apache License, Version 2.0 (the "License");
6 | * you may not use this file except in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | */
17 |
18 | #include "shelly_hap_contact_sensor.hpp"
19 |
20 | namespace shelly {
21 | namespace hap {
22 |
23 | ContactSensor::ContactSensor(int id, Input *in,
24 | struct mgos_config_in_sensor *cfg)
25 | : SensorBase(id, in, cfg, SHELLY_HAP_IID_BASE_CONTACT_SENSOR,
26 | &kHAPServiceType_ContactSensor,
27 | kHAPServiceDebugDescription_ContactSensor) {
28 | }
29 |
30 | ContactSensor::~ContactSensor() {
31 | }
32 |
33 | Component::Type ContactSensor::type() const {
34 | return Type::kContactSensor;
35 | }
36 |
37 | Status ContactSensor::Init() {
38 | const Status &st = SensorBase::Init();
39 | if (!st.ok()) return st;
40 | AddChar(new mgos::hap::UInt8Characteristic(
41 | svc_.iid + 2, &kHAPCharacteristicType_ContactSensorState, 0, 1, 1,
42 | [this](HAPAccessoryServerRef *, const HAPUInt8CharacteristicReadRequest *,
43 | uint8_t *value) {
44 | *value = !state_;
45 | return kHAPError_None;
46 | },
47 | true /* supports_notification */, nullptr /* write_handler */,
48 | kHAPCharacteristicDebugDescription_ContactSensorState));
49 | return Status::OK();
50 | }
51 |
52 | } // namespace hap
53 | } // namespace shelly
54 |
--------------------------------------------------------------------------------
/src/shelly_hap_contact_sensor.hpp:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) Shelly-HomeKit Contributors
3 | * All rights reserved
4 | *
5 | * Licensed under the Apache License, Version 2.0 (the "License");
6 | * you may not use this file except in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | */
17 |
18 | #pragma once
19 |
20 | #include "shelly_hap_sensor_base.hpp"
21 |
22 | namespace shelly {
23 | namespace hap {
24 |
25 | class ContactSensor : public SensorBase {
26 | public:
27 | ContactSensor(int id, Input *in, struct mgos_config_in_sensor *cfg);
28 | virtual ~ContactSensor();
29 |
30 | // Component interface impl.
31 | Status Init() override;
32 | virtual Type type() const override;
33 | };
34 |
35 | } // namespace hap
36 | } // namespace shelly
37 |
--------------------------------------------------------------------------------
/src/shelly_hap_doorbell.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) Shelly-HomeKit Contributors
3 | * All rights reserved
4 | *
5 | * Licensed under the Apache License, Version 2.0 (the "License");
6 | * you may not use this file except in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | */
17 |
18 | #include "shelly_hap_doorbell.hpp"
19 |
20 | #include "HAPUUID.h"
21 |
22 | namespace shelly {
23 | namespace hap {
24 |
25 | const HAPUUID kHAPServiceType_Doorbell = HAPUUIDCreateAppleDefined(0x121);
26 |
27 | Doorbell::Doorbell(int id, Input *in, struct mgos_config_in_ssw *cfg)
28 | : StatelessSwitchBase(id, in, cfg, SHELLY_HAP_IID_BASE_DOORBELL,
29 | &kHAPServiceType_Doorbell, "service.doorbell") {
30 | }
31 |
32 | Doorbell::~Doorbell() {
33 | }
34 |
35 | Component::Type Doorbell::type() const {
36 | return Type::kDoorbell;
37 | }
38 |
39 | } // namespace hap
40 | } // namespace shelly
--------------------------------------------------------------------------------
/src/shelly_hap_doorbell.hpp:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) Shelly-HomeKit Contributors
3 | * All rights reserved
4 | *
5 | * Licensed under the Apache License, Version 2.0 (the "License");
6 | * you may not use this file except in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | */
17 |
18 | #pragma once
19 | #include "shelly_hap_stateless_switch_base.hpp"
20 |
21 | namespace shelly {
22 | namespace hap {
23 |
24 | class Doorbell : public StatelessSwitchBase {
25 | public:
26 | Doorbell(int id, Input *in, struct mgos_config_in_ssw *cfg);
27 | virtual ~Doorbell();
28 |
29 | // Component interface impl.
30 | Type type() const override;
31 | };
32 |
33 | } // namespace hap
34 | } // namespace shelly
--------------------------------------------------------------------------------
/src/shelly_hap_garage_door_opener.hpp:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) Shelly-HomeKit Contributors
3 | * All rights reserved
4 | *
5 | * Licensed under the Apache License, Version 2.0 (the "License");
6 | * you may not use this file except in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | */
17 |
18 | #pragma once
19 |
20 | #include
21 | #include
22 |
23 | #include "mgos_hap_chars.hpp"
24 | #include "mgos_hap_service.hpp"
25 | #include "mgos_sys_config.h"
26 | #include "mgos_timers.hpp"
27 |
28 | #include "shelly_common.hpp"
29 | #include "shelly_component.hpp"
30 | #include "shelly_input.hpp"
31 | #include "shelly_output.hpp"
32 |
33 | namespace shelly {
34 | namespace hap {
35 |
36 | // Common base for Switch, Outlet and Lock services.
37 | class GarageDoorOpener : public Component, public mgos::hap::Service {
38 | public:
39 | GarageDoorOpener(int id, Input *in_close, Input *in_open, Output *out_open,
40 | Output *out_close, struct mgos_config_gdo *cfg);
41 | virtual ~GarageDoorOpener();
42 |
43 | // Component interface impl.
44 | Type type() const override;
45 | std::string name() const override;
46 | Status Init() override;
47 | StatusOr GetInfo() const override;
48 | StatusOr GetInfoJSON() const override;
49 | Status SetConfig(const std::string &config_json,
50 | bool *restart_required) override;
51 | Status SetState(const std::string &state_json) override;
52 | bool IsIdle() override;
53 |
54 | private:
55 | // NB: Values correspond to HAP Current Door State values.
56 | enum class State {
57 | kOpen = 0,
58 | kClosed = 1,
59 | kOpening = 2,
60 | kClosing = 3,
61 | kStopped = 4,
62 | };
63 |
64 | static const char *StateStr(State state);
65 |
66 | void GetInputsState(int *is_closed, int *is_open) const;
67 | void SetCurState(State new_state);
68 | void SetTgtState(State new_state, const char *source);
69 | void ToggleState(const char *source);
70 | HAPError HAPTgtStateWrite(HAPAccessoryServerRef *svr,
71 | const HAPUInt8CharacteristicWriteRequest *req,
72 | uint8_t value);
73 |
74 | void RunOnce();
75 |
76 | Input *in_close_, *in_open_;
77 | Output *out_close_, *out_open_;
78 | struct mgos_config_gdo *cfg_;
79 |
80 | mgos::Timer state_timer_;
81 |
82 | mgos::hap::Characteristic *cur_state_char_ = nullptr;
83 | mgos::hap::Characteristic *tgt_state_char_ = nullptr;
84 | mgos::hap::Characteristic *obst_char_ = nullptr;
85 |
86 | State cur_state_;
87 | State tgt_state_;
88 | State pre_stopped_state_;
89 | int64_t begin_ = 0;
90 | bool obstruction_detected_ = false;
91 | };
92 |
93 | void CreateHAPGDO(int id, Input *in_close, Input *in_open, Output *out_close,
94 | Output *out_open, const struct mgos_config_gdo *gdo_cfg,
95 | std::vector> *comps,
96 | std::vector> *accs,
97 | HAPAccessoryServerRef *svr, bool to_pri_acc);
98 |
99 | } // namespace hap
100 | } // namespace shelly
101 |
--------------------------------------------------------------------------------
/src/shelly_hap_humidity_sensor.hpp:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) Shelly-HomeKit Contributors
3 | * All rights reserved
4 | *
5 | * Licensed under the Apache License, Version 2.0 (the "License");
6 | * you may not use this file except in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | */
17 |
18 | #pragma once
19 |
20 | #include "mgos_hap_service.hpp"
21 | #include "mgos_sys_config.h"
22 |
23 | #include "shelly_common.hpp"
24 | #include "shelly_component.hpp"
25 | #include "shelly_temp_sensor.hpp"
26 |
27 | namespace shelly {
28 | namespace hap {
29 |
30 | class HumiditySensor : public Component, public mgos::hap::Service {
31 | public:
32 | HumiditySensor(int id, HumidityTempSensor *sensor,
33 | struct mgos_config_ts *cfg);
34 | virtual ~HumiditySensor();
35 |
36 | // Component interface impl.
37 | Type type() const override;
38 | std::string name() const override;
39 | Status Init() override;
40 |
41 | StatusOr GetInfo() const override;
42 | StatusOr GetInfoJSON() const override;
43 | Status SetConfig(const std::string &config_json,
44 | bool *restart_required) override;
45 | Status SetState(const std::string &state_json) override;
46 |
47 | private:
48 | HumidityTempSensor *hum_sensor_;
49 | struct mgos_config_ts *cfg_;
50 |
51 | mgos::hap::FloatCharacteristic *current_humidity_characteristic_;
52 |
53 | void ValueChanged();
54 | };
55 |
56 | void CreateHAPHumiditySensor(
57 | int id, HumidityTempSensor *sensor, const struct mgos_config_ts *ts_cfg,
58 | std::vector> *comps,
59 | std::vector> *accs,
60 | HAPAccessoryServerRef *svr);
61 |
62 | } // namespace hap
63 | } // namespace shelly
64 |
--------------------------------------------------------------------------------
/src/shelly_hap_input.hpp:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) Shelly-HomeKit Contributors
3 | * All rights reserved
4 | *
5 | * Licensed under the Apache License, Version 2.0 (the "License");
6 | * you may not use this file except in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | */
17 |
18 | #pragma once
19 |
20 | #include
21 | #include
22 |
23 | #include "mgos_hap.hpp"
24 | #include "mgos_sys_config.h"
25 |
26 | #include "shelly_common.hpp"
27 | #include "shelly_component.hpp"
28 | #include "shelly_input.hpp"
29 |
30 | namespace shelly {
31 | namespace hap {
32 |
33 | // A service that represents a single Shelly input.
34 | // Internally it instantiates either a Stateless Switch or Motion Sensor
35 | // and forwards API calls to it.
36 | class ShellyInput : public Component {
37 | public:
38 | ShellyInput(int id, Input *in, struct mgos_config_in *cfg);
39 | virtual ~ShellyInput();
40 |
41 | // Component interface impl.
42 | Type type() const override;
43 | Status Init() override;
44 | std::string name() const override;
45 | StatusOr GetInfo() const override;
46 | StatusOr GetInfoJSON() const override;
47 | Status SetConfig(const std::string &config_json,
48 | bool *restart_required) override;
49 | Status SetState(const std::string &state_json) override;
50 |
51 | uint16_t GetAIDBase() const;
52 | mgos::hap::Service *GetService() const;
53 |
54 | private:
55 | static bool IsValidType(int type);
56 |
57 | Input *const in_;
58 | struct mgos_config_in *cfg_;
59 | Type initial_type_; // Type at creation.
60 |
61 | std::unique_ptr c_;
62 | mgos::hap::Service *s_ = nullptr;
63 |
64 | ShellyInput(const ShellyInput &other) = delete;
65 | };
66 |
67 | void CreateHAPInput(int id, const struct mgos_config_in *cfg,
68 | std::vector> *comps,
69 | std::vector> *accs,
70 | HAPAccessoryServerRef *svr);
71 |
72 | } // namespace hap
73 | } // namespace shelly
74 |
--------------------------------------------------------------------------------
/src/shelly_hap_leak_sensor.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) Shelly-HomeKit Contributors
3 | * All rights reserved
4 | *
5 | * Licensed under the Apache License, Version 2.0 (the "License");
6 | * you may not use this file except in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | */
17 |
18 | #include "shelly_hap_leak_sensor.hpp"
19 |
20 | namespace shelly {
21 | namespace hap {
22 |
23 | LeakSensor::LeakSensor(int id, Input *in, struct mgos_config_in_sensor *cfg)
24 | : SensorBase(id, in, cfg, SHELLY_HAP_IID_BASE_LEAK_SENSOR,
25 | &kHAPServiceType_LeakSensor,
26 | kHAPServiceDebugDescription_LeakSensor) {
27 | }
28 |
29 | LeakSensor::~LeakSensor() {
30 | }
31 |
32 | Component::Type LeakSensor::type() const {
33 | return Type::kLeakSensor;
34 | }
35 |
36 | Status LeakSensor::Init() {
37 | const Status &st = SensorBase::Init();
38 | if (!st.ok()) return st;
39 | AddChar(new mgos::hap::UInt8Characteristic(
40 | svc_.iid + 2, &kHAPCharacteristicType_LeakDetected, 0, 1, 1,
41 | std::bind(&mgos::hap::ReadUInt8, _1, _2, _3, &state_),
42 | true /* supports_notification */, nullptr /* write_handler */,
43 | kHAPCharacteristicDebugDescription_LeakDetected));
44 | return Status::OK();
45 | }
46 |
47 | } // namespace hap
48 | } // namespace shelly
49 |
--------------------------------------------------------------------------------
/src/shelly_hap_leak_sensor.hpp:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) Shelly-HomeKit Contributors
3 | * All rights reserved
4 | *
5 | * Licensed under the Apache License, Version 2.0 (the "License");
6 | * you may not use this file except in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | */
17 |
18 | #pragma once
19 |
20 | #include "shelly_hap_sensor_base.hpp"
21 |
22 | namespace shelly {
23 | namespace hap {
24 |
25 | class LeakSensor : public SensorBase {
26 | public:
27 | LeakSensor(int id, Input *in, struct mgos_config_in_sensor *cfg);
28 | virtual ~LeakSensor();
29 |
30 | // Component interface impl.
31 | Status Init() override;
32 | virtual Type type() const override;
33 | };
34 |
35 | } // namespace hap
36 | } // namespace shelly
37 |
--------------------------------------------------------------------------------
/src/shelly_hap_lock.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) Shelly-HomeKit Contributors
3 | * All rights reserved
4 | *
5 | * Licensed under the Apache License, Version 2.0 (the "License");
6 | * you may not use this file except in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | */
17 |
18 | #include "shelly_hap_lock.hpp"
19 |
20 | #include "mgos_hap_accessory.hpp"
21 |
22 | namespace shelly {
23 | namespace hap {
24 |
25 | Lock::Lock(int id, Input *in, Output *out, PowerMeter *out_pm, Output *led_out,
26 | struct mgos_config_sw *cfg)
27 | : ShellySwitch(id, in, out, out_pm, led_out, cfg) {
28 | }
29 |
30 | Lock::~Lock() {
31 | }
32 |
33 | Status Lock::Init() {
34 | auto st = ShellySwitch::Init();
35 | if (!st.ok()) return st;
36 |
37 | const int id1 = id() - 1; // IDs used to start at 0, preserve compat.
38 | uint16_t iid = SHELLY_HAP_IID_BASE_LOCK + (SHELLY_HAP_IID_STEP_LOCK * id1);
39 | svc_.iid = iid++;
40 | svc_.serviceType = &kHAPServiceType_LockMechanism;
41 | svc_.debugDescription = kHAPServiceDebugDescription_LockMechanism;
42 | // Name
43 | AddNameChar(iid++, cfg_->name);
44 | // Current State
45 | auto *cur_state_char = new mgos::hap::UInt8Characteristic(
46 | iid++, &kHAPCharacteristicType_LockCurrentState, 0, 3, 1,
47 | std::bind(&Lock::HandleCurrentStateRead, this, _1, _2, _3),
48 | true /* supports_notification */, nullptr /* write_handler */,
49 | kHAPCharacteristicDebugDescription_LockCurrentState);
50 | state_notify_chars_.push_back(cur_state_char);
51 | AddChar(cur_state_char);
52 | // Target State
53 | auto *tgt_state_char = new mgos::hap::UInt8Characteristic(
54 | iid++, &kHAPCharacteristicType_LockTargetState, 0, 3, 1,
55 | std::bind(&Lock::HandleCurrentStateRead, this, _1, _2, _3),
56 | true /* supports_notification */,
57 | [this](HAPAccessoryServerRef *server UNUSED_ARG,
58 | const HAPUInt8CharacteristicWriteRequest *request UNUSED_ARG,
59 | uint8_t value) {
60 | SetOutputState((value == 0), "HAP");
61 | state_notify_chars_[1]->RaiseEvent();
62 | return kHAPError_None;
63 | },
64 | kHAPCharacteristicDebugDescription_LockTargetState);
65 | state_notify_chars_.push_back(tgt_state_char);
66 | AddChar(tgt_state_char);
67 |
68 | return Status::OK();
69 | }
70 |
71 | HAPError Lock::HandleCurrentStateRead(
72 | HAPAccessoryServerRef *server,
73 | const HAPUInt8CharacteristicReadRequest *request, uint8_t *value) {
74 | *value = (out_->GetState() ? 0 : 1);
75 | (void) server;
76 | (void) request;
77 | return kHAPError_None;
78 | }
79 |
80 | } // namespace hap
81 | } // namespace shelly
82 |
--------------------------------------------------------------------------------
/src/shelly_hap_lock.hpp:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) Shelly-HomeKit Contributors
3 | * All rights reserved
4 | *
5 | * Licensed under the Apache License, Version 2.0 (the "License");
6 | * you may not use this file except in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | */
17 |
18 | #pragma once
19 |
20 | #include "mgos_hap_chars.hpp"
21 | #include "shelly_switch.hpp"
22 |
23 | namespace shelly {
24 | namespace hap {
25 |
26 | class Lock : public ShellySwitch {
27 | public:
28 | Lock(int id, Input *in, Output *out, PowerMeter *out_pm, Output *led_out,
29 | struct mgos_config_sw *cfg);
30 | virtual ~Lock();
31 |
32 | Status Init();
33 |
34 | private:
35 | HAPError HandleCurrentStateRead(
36 | HAPAccessoryServerRef *server,
37 | const HAPUInt8CharacteristicReadRequest *request, uint8_t *value);
38 | };
39 |
40 | } // namespace hap
41 | } // namespace shelly
42 |
--------------------------------------------------------------------------------
/src/shelly_hap_motion_sensor.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) Shelly-HomeKit Contributors
3 | * All rights reserved
4 | *
5 | * Licensed under the Apache License, Version 2.0 (the "License");
6 | * you may not use this file except in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | */
17 |
18 | #include "shelly_hap_motion_sensor.hpp"
19 |
20 | namespace shelly {
21 | namespace hap {
22 |
23 | MotionSensor::MotionSensor(int id, Input *in, struct mgos_config_in_sensor *cfg)
24 | : SensorBase(id, in, cfg, SHELLY_HAP_IID_BASE_MOTION_SENSOR,
25 | &kHAPServiceType_MotionSensor,
26 | kHAPServiceDebugDescription_MotionSensor) {
27 | }
28 |
29 | MotionSensor::~MotionSensor() {
30 | }
31 |
32 | Component::Type MotionSensor::type() const {
33 | return Type::kMotionSensor;
34 | }
35 |
36 | Status MotionSensor::Init() {
37 | const Status &st = SensorBase::Init();
38 | if (!st.ok()) return st;
39 | AddChar(new mgos::hap::BoolCharacteristic(
40 | svc_.iid + 2, &kHAPCharacteristicType_MotionDetected,
41 | std::bind(&mgos::hap::ReadBool, _1, _2, _3, &state_),
42 | true /* supports_notification */, nullptr /* write_handler */,
43 | kHAPCharacteristicDebugDescription_MotionDetected));
44 | return Status::OK();
45 | }
46 |
47 | } // namespace hap
48 | } // namespace shelly
49 |
--------------------------------------------------------------------------------
/src/shelly_hap_motion_sensor.hpp:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) Shelly-HomeKit Contributors
3 | * All rights reserved
4 | *
5 | * Licensed under the Apache License, Version 2.0 (the "License");
6 | * you may not use this file except in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | */
17 |
18 | #pragma once
19 |
20 | #include "shelly_hap_sensor_base.hpp"
21 |
22 | namespace shelly {
23 | namespace hap {
24 |
25 | class MotionSensor : public SensorBase {
26 | public:
27 | MotionSensor(int id, Input *in, struct mgos_config_in_sensor *cfg);
28 | virtual ~MotionSensor();
29 |
30 | // Component interface impl.
31 | Status Init() override;
32 | virtual Type type() const override;
33 | };
34 |
35 | } // namespace hap
36 | } // namespace shelly
37 |
--------------------------------------------------------------------------------
/src/shelly_hap_occupancy_sensor.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) Shelly-HomeKit Contributors
3 | * All rights reserved
4 | *
5 | * Licensed under the Apache License, Version 2.0 (the "License");
6 | * you may not use this file except in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | */
17 |
18 | #include "shelly_hap_occupancy_sensor.hpp"
19 |
20 | namespace shelly {
21 | namespace hap {
22 |
23 | OccupancySensor::OccupancySensor(int id, Input *in,
24 | struct mgos_config_in_sensor *cfg)
25 | : SensorBase(id, in, cfg, SHELLY_HAP_IID_BASE_OCCUPANCY_SENSOR,
26 | &kHAPServiceType_OccupancySensor,
27 | kHAPServiceDebugDescription_OccupancySensor) {
28 | }
29 |
30 | OccupancySensor::~OccupancySensor() {
31 | }
32 |
33 | Component::Type OccupancySensor::type() const {
34 | return Type::kOccupancySensor;
35 | }
36 |
37 | Status OccupancySensor::Init() {
38 | const Status &st = SensorBase::Init();
39 | if (!st.ok()) return st;
40 | AddChar(new mgos::hap::BoolCharacteristic(
41 | svc_.iid + 2, &kHAPCharacteristicType_OccupancyDetected,
42 | std::bind(&mgos::hap::ReadBool, _1, _2, _3, &state_),
43 | true /* supports_notification */, nullptr /* write_handler */,
44 | kHAPCharacteristicDebugDescription_OccupancyDetected));
45 | return Status::OK();
46 | }
47 |
48 | } // namespace hap
49 | } // namespace shelly
50 |
--------------------------------------------------------------------------------
/src/shelly_hap_occupancy_sensor.hpp:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) Shelly-HomeKit Contributors
3 | * All rights reserved
4 | *
5 | * Licensed under the Apache License, Version 2.0 (the "License");
6 | * you may not use this file except in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | */
17 |
18 | #pragma once
19 |
20 | #include "shelly_hap_sensor_base.hpp"
21 |
22 | namespace shelly {
23 | namespace hap {
24 |
25 | class OccupancySensor : public SensorBase {
26 | public:
27 | OccupancySensor(int id, Input *in, struct mgos_config_in_sensor *cfg);
28 | virtual ~OccupancySensor();
29 |
30 | // Component interface impl.
31 | Status Init() override;
32 | virtual Type type() const override;
33 | };
34 |
35 | } // namespace hap
36 | } // namespace shelly
37 |
--------------------------------------------------------------------------------
/src/shelly_hap_outlet.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) Shelly-HomeKit Contributors
3 | * All rights reserved
4 | *
5 | * Licensed under the Apache License, Version 2.0 (the "License");
6 | * you may not use this file except in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | */
17 |
18 | #include "shelly_hap_outlet.hpp"
19 |
20 | namespace shelly {
21 | namespace hap {
22 |
23 | Outlet::Outlet(int id, Input *in, Output *out, PowerMeter *out_pm,
24 | Output *led_out, struct mgos_config_sw *cfg)
25 | : ShellySwitch(id, in, out, out_pm, led_out, cfg) {
26 | }
27 |
28 | Outlet::~Outlet() {
29 | }
30 |
31 | Status Outlet::Init() {
32 | auto st = ShellySwitch::Init();
33 | if (!st.ok()) return st;
34 |
35 | const int id1 = id() - 1; // IDs used to start at 0, preserve compat.
36 | uint16_t iid =
37 | SHELLY_HAP_IID_BASE_OUTLET + (SHELLY_HAP_IID_STEP_OUTLET * id1);
38 | svc_.iid = iid++;
39 | svc_.serviceType = &kHAPServiceType_Outlet;
40 | svc_.debugDescription = kHAPServiceDebugDescription_Outlet;
41 | // Name
42 | AddNameChar(iid++, cfg_->name);
43 | // On
44 | auto *on_char = new mgos::hap::BoolCharacteristic(
45 | iid++, &kHAPCharacteristicType_On,
46 | [this](HAPAccessoryServerRef *, const HAPBoolCharacteristicReadRequest *,
47 | bool *value) {
48 | *value = out_->GetState() ^ cfg_->hk_state_inverted;
49 | return kHAPError_None;
50 | },
51 | true /* supports_notification */,
52 | [this](HAPAccessoryServerRef *, const HAPBoolCharacteristicWriteRequest *,
53 | bool value) {
54 | SetOutputState(value ^ cfg_->hk_state_inverted, "HAP");
55 | return kHAPError_None;
56 | },
57 | kHAPCharacteristicDebugDescription_On);
58 | state_notify_chars_.push_back(on_char);
59 | AddChar(on_char);
60 | // Outlet In Use
61 | AddChar(new mgos::hap::BoolCharacteristic(
62 | iid++, &kHAPCharacteristicType_OutletInUse,
63 | [](HAPAccessoryServerRef *, const HAPBoolCharacteristicReadRequest *,
64 | bool *value) {
65 | *value = true;
66 | return kHAPError_None;
67 | },
68 | true /* supports_notification */, nullptr /* write_handler */,
69 | kHAPCharacteristicDebugDescription_OutletInUse));
70 |
71 | // Power
72 | AddPowerMeter(&iid);
73 |
74 | return Status::OK();
75 | }
76 |
77 | } // namespace hap
78 | } // namespace shelly
79 |
--------------------------------------------------------------------------------
/src/shelly_hap_outlet.hpp:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) Shelly-HomeKit Contributors
3 | * All rights reserved
4 | *
5 | * Licensed under the Apache License, Version 2.0 (the "License");
6 | * you may not use this file except in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | */
17 |
18 | #pragma once
19 |
20 | #include "shelly_switch.hpp"
21 |
22 | namespace shelly {
23 | namespace hap {
24 |
25 | class Outlet : public ShellySwitch {
26 | public:
27 | Outlet(int id, Input *in, Output *out, PowerMeter *out_pm, Output *led_out,
28 | struct mgos_config_sw *cfg);
29 | virtual ~Outlet();
30 |
31 | Status Init();
32 | };
33 |
34 | } // namespace hap
35 | } // namespace shelly
36 |
--------------------------------------------------------------------------------
/src/shelly_hap_sensor_base.hpp:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) Shelly-HomeKit Contributors
3 | * All rights reserved
4 | *
5 | * Licensed under the Apache License, Version 2.0 (the "License");
6 | * you may not use this file except in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | */
17 |
18 | #pragma once
19 |
20 | #include "mgos_hap_service.hpp"
21 | #include "mgos_sys_config.h"
22 | #include "mgos_timers.hpp"
23 |
24 | #include "shelly_common.hpp"
25 | #include "shelly_component.hpp"
26 | #include "shelly_input.hpp"
27 |
28 | namespace shelly {
29 | namespace hap {
30 |
31 | class SensorBase : public Component, public mgos::hap::Service {
32 | public:
33 | enum class InMode {
34 | kLevel = 0,
35 | kPulse = 1,
36 | kMax,
37 | };
38 |
39 | SensorBase(int id, Input *in, struct mgos_config_in_sensor *cfg,
40 | uint16_t iid_base, const HAPUUID *type,
41 | const char *debug_description);
42 | virtual ~SensorBase();
43 |
44 | // Component interface impl.
45 | virtual Status Init() override;
46 | std::string name() const override;
47 | StatusOr GetInfo() const override;
48 | StatusOr GetInfoJSON() const override;
49 | Status SetConfig(const std::string &config_json,
50 | bool *restart_required) override;
51 | Status SetState(const std::string &state_json) override;
52 |
53 | protected:
54 | bool state_ = false;
55 |
56 | private:
57 | void InputEventHandler(Input::Event ev, bool state);
58 | void SetInternalState(bool motion_detected);
59 | void AutoOffTimerCB();
60 |
61 | Input *const in_;
62 | struct mgos_config_in_sensor *cfg_;
63 |
64 | Input::HandlerID handler_id_ = Input::kInvalidHandlerID;
65 |
66 | double last_ev_ts_ = 0;
67 | mgos::Timer auto_off_timer_;
68 |
69 | SensorBase(const SensorBase &other) = delete;
70 | };
71 |
72 | } // namespace hap
73 | } // namespace shelly
74 |
--------------------------------------------------------------------------------
/src/shelly_hap_smoke_sensor.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) Shelly-HomeKit Contributors
3 | * All rights reserved
4 | *
5 | * Licensed under the Apache License, Version 2.0 (the "License");
6 | * you may not use this file except in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | */
17 |
18 | #include "shelly_hap_smoke_sensor.hpp"
19 |
20 | namespace shelly {
21 | namespace hap {
22 |
23 | SmokeSensor::SmokeSensor(int id, Input *in, struct mgos_config_in_sensor *cfg)
24 | : SensorBase(id, in, cfg, SHELLY_HAP_IID_BASE_SMOKE_SENSOR,
25 | &kHAPServiceType_SmokeSensor,
26 | kHAPServiceDebugDescription_SmokeSensor) {
27 | }
28 |
29 | SmokeSensor::~SmokeSensor() {
30 | }
31 |
32 | Component::Type SmokeSensor::type() const {
33 | return Type::kSmokeSensor;
34 | }
35 |
36 | Status SmokeSensor::Init() {
37 | const Status &st = SensorBase::Init();
38 | if (!st.ok()) return st;
39 | AddChar(new mgos::hap::UInt8Characteristic(
40 | svc_.iid + 2, &kHAPCharacteristicType_SmokeDetected, 0, 1, 1,
41 | std::bind(&mgos::hap::ReadUInt8, _1, _2, _3, &state_),
42 | true /* supports_notification */, nullptr /* write_handler */,
43 | kHAPCharacteristicDebugDescription_SmokeDetected));
44 | return Status::OK();
45 | }
46 |
47 | } // namespace hap
48 | } // namespace shelly
49 |
--------------------------------------------------------------------------------
/src/shelly_hap_smoke_sensor.hpp:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) Shelly-HomeKit Contributors
3 | * All rights reserved
4 | *
5 | * Licensed under the Apache License, Version 2.0 (the "License");
6 | * you may not use this file except in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | */
17 |
18 | #pragma once
19 |
20 | #include "shelly_hap_sensor_base.hpp"
21 |
22 | namespace shelly {
23 | namespace hap {
24 |
25 | class SmokeSensor : public SensorBase {
26 | public:
27 | SmokeSensor(int id, Input *in, struct mgos_config_in_sensor *cfg);
28 | virtual ~SmokeSensor();
29 |
30 | // Component interface impl.
31 | Status Init() override;
32 | virtual Type type() const override;
33 | };
34 |
35 | } // namespace hap
36 | } // namespace shelly
37 |
--------------------------------------------------------------------------------
/src/shelly_hap_stateless_switch.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) Shelly-HomeKit Contributors
3 | * All rights reserved
4 | *
5 | * Licensed under the Apache License, Version 2.0 (the "License");
6 | * you may not use this file except in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | */
17 |
18 | #include "shelly_hap_stateless_switch.hpp"
19 |
20 | namespace shelly {
21 | namespace hap {
22 |
23 | StatelessSwitch::StatelessSwitch(int id, Input *in,
24 | struct mgos_config_in_ssw *cfg)
25 | : StatelessSwitchBase(
26 | id, in, cfg, SHELLY_HAP_IID_BASE_STATELESS_SWITCH,
27 | &kHAPServiceType_StatelessProgrammableSwitch,
28 | kHAPServiceDebugDescription_StatelessProgrammableSwitch) {
29 | }
30 |
31 | StatelessSwitch::~StatelessSwitch() {
32 | }
33 |
34 | Component::Type StatelessSwitch::type() const {
35 | return Type::kStatelessSwitch;
36 | }
37 |
38 | } // namespace hap
39 | } // namespace shelly
--------------------------------------------------------------------------------
/src/shelly_hap_stateless_switch.hpp:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) Shelly-HomeKit Contributors
3 | * All rights reserved
4 | *
5 | * Licensed under the Apache License, Version 2.0 (the "License");
6 | * you may not use this file except in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | */
17 |
18 | #pragma once
19 | #include "shelly_hap_stateless_switch_base.hpp"
20 |
21 | namespace shelly {
22 | namespace hap {
23 |
24 | class StatelessSwitch : public StatelessSwitchBase {
25 | public:
26 | StatelessSwitch(int id, Input *in, struct mgos_config_in_ssw *cfg);
27 | virtual ~StatelessSwitch();
28 |
29 | // Component interface impl.
30 | Type type() const override;
31 | };
32 |
33 | } // namespace hap
34 | } // namespace shelly
--------------------------------------------------------------------------------
/src/shelly_hap_stateless_switch_base.hpp:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) Shelly-HomeKit Contributors
3 | * All rights reserved
4 | *
5 | * Licensed under the Apache License, Version 2.0 (the "License");
6 | * you may not use this file except in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | */
17 |
18 | #pragma once
19 |
20 | #include
21 | #include
22 |
23 | #include "mgos_hap.hpp"
24 | #include "mgos_sys_config.h"
25 | #include "mgos_timers.h"
26 |
27 | #include "shelly_common.hpp"
28 | #include "shelly_component.hpp"
29 | #include "shelly_input.hpp"
30 | #include "shelly_output.hpp"
31 | #include "shelly_pm.hpp"
32 |
33 | namespace shelly {
34 | namespace hap {
35 |
36 | // Common base for Switch, Outlet and Lock services.
37 | class StatelessSwitchBase : public Component, public mgos::hap::Service {
38 | public:
39 | enum class InMode {
40 | kMomentary = 0,
41 | kToggleShort = 1,
42 | kToggleShortLong = 2,
43 | };
44 |
45 | StatelessSwitchBase(int id, Input *in, struct mgos_config_in_ssw *cfg,
46 | uint16_t iid_base, const HAPUUID *type,
47 | const char *debug_description);
48 | virtual ~StatelessSwitchBase();
49 |
50 | // Component interface impl.
51 | Status Init() override;
52 | Type type() const override;
53 | std::string name() const override;
54 | StatusOr GetInfo() const override;
55 | StatusOr GetInfoJSON() const override;
56 | Status SetConfig(const std::string &config_json,
57 | bool *restart_required) override;
58 | Status SetState(const std::string &state_json) override;
59 |
60 | private:
61 | void InputEventHandler(Input::Event ev, bool state);
62 |
63 | void RaiseEvent(uint8_t ev);
64 |
65 | Input *const in_;
66 | struct mgos_config_in_ssw *cfg_;
67 |
68 | Input::HandlerID handler_id_ = Input::kInvalidHandlerID;
69 |
70 | uint8_t last_ev_ = 0;
71 | double last_ev_ts_ = 0;
72 |
73 | StatelessSwitchBase(const StatelessSwitchBase &other) = delete;
74 | };
75 |
76 | } // namespace hap
77 | } // namespace shelly
78 |
--------------------------------------------------------------------------------
/src/shelly_hap_switch.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) Shelly-HomeKit Contributors
3 | * All rights reserved
4 | *
5 | * Licensed under the Apache License, Version 2.0 (the "License");
6 | * you may not use this file except in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | */
17 |
18 | #include "shelly_hap_switch.hpp"
19 |
20 | #include "mgos.hpp"
21 | #include "mgos_hap_chars.hpp"
22 |
23 | namespace shelly {
24 | namespace hap {
25 |
26 | Switch::Switch(int id, Input *in, Output *out, PowerMeter *out_pm,
27 | Output *led_out, struct mgos_config_sw *cfg)
28 | : ShellySwitch(id, in, out, out_pm, led_out, cfg) {
29 | }
30 |
31 | Switch::~Switch() {
32 | }
33 |
34 | Status Switch::Init() {
35 | auto st = ShellySwitch::Init();
36 | if (!st.ok()) return st;
37 |
38 | const int id1 = id() - 1; // IDs used to start at 0, preserve compat.
39 | uint16_t iid =
40 | SHELLY_HAP_IID_BASE_SWITCH + (SHELLY_HAP_IID_STEP_SWITCH * id1);
41 | svc_.iid = iid++;
42 | svc_.serviceType = &kHAPServiceType_Switch;
43 | svc_.debugDescription = kHAPServiceDebugDescription_Switch;
44 | // Name
45 | AddNameChar(iid++, cfg_->name);
46 | // On
47 | auto *on_char = new mgos::hap::BoolCharacteristic(
48 | iid++, &kHAPCharacteristicType_On,
49 | [this](HAPAccessoryServerRef *, const HAPBoolCharacteristicReadRequest *,
50 | bool *value) {
51 | *value = out_->GetState() ^ cfg_->hk_state_inverted;
52 | return kHAPError_None;
53 | },
54 | true /* supports_notification */,
55 | [this](HAPAccessoryServerRef *, const HAPBoolCharacteristicWriteRequest *,
56 | bool value) {
57 | SetOutputState(value ^ cfg_->hk_state_inverted, "HAP");
58 | return kHAPError_None;
59 | },
60 | kHAPCharacteristicDebugDescription_On);
61 | state_notify_chars_.push_back(on_char);
62 | AddChar(on_char);
63 |
64 | // Power
65 | AddPowerMeter(&iid);
66 |
67 | out_->SetInvert(cfg_->out_inverted);
68 |
69 | return Status::OK();
70 | }
71 |
72 | } // namespace hap
73 | } // namespace shelly
74 |
--------------------------------------------------------------------------------
/src/shelly_hap_switch.hpp:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) Shelly-HomeKit Contributors
3 | * All rights reserved
4 | *
5 | * Licensed under the Apache License, Version 2.0 (the "License");
6 | * you may not use this file except in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | */
17 |
18 | #pragma once
19 |
20 | #include
21 | #include
22 |
23 | #include "mgos_hap.hpp"
24 | #include "mgos_sys_config.h"
25 | #include "mgos_timers.h"
26 |
27 | #include "shelly_common.hpp"
28 | #include "shelly_component.hpp"
29 | #include "shelly_input.hpp"
30 | #include "shelly_output.hpp"
31 | #include "shelly_pm.hpp"
32 | #include "shelly_switch.hpp"
33 |
34 | namespace shelly {
35 | namespace hap {
36 |
37 | class Switch : public ShellySwitch {
38 | public:
39 | Switch(int id, Input *in, Output *out, PowerMeter *out_pm, Output *led_out,
40 | struct mgos_config_sw *cfg);
41 | virtual ~Switch();
42 |
43 | Status Init();
44 | };
45 |
46 | } // namespace hap
47 | } // namespace shelly
48 |
--------------------------------------------------------------------------------
/src/shelly_hap_temperature_sensor.hpp:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) Shelly-HomeKit Contributors
3 | * All rights reserved
4 | *
5 | * Licensed under the Apache License, Version 2.0 (the "License");
6 | * you may not use this file except in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | */
17 |
18 | #pragma once
19 |
20 | #include "mgos_hap_service.hpp"
21 | #include "mgos_sys_config.h"
22 |
23 | #include "shelly_common.hpp"
24 | #include "shelly_component.hpp"
25 |
26 | #include "shelly_temp_sensor.hpp"
27 |
28 | namespace shelly {
29 | namespace hap {
30 |
31 | class TemperatureSensor : public Component, public mgos::hap::Service {
32 | public:
33 | TemperatureSensor(int id, TempSensor *sensor, struct mgos_config_ts *cfg);
34 | virtual ~TemperatureSensor();
35 |
36 | // Component interface impl.
37 | Type type() const override;
38 | std::string name() const override;
39 | Status Init() override;
40 |
41 | StatusOr GetInfo() const override;
42 | StatusOr GetInfoJSON() const override;
43 | Status SetConfig(const std::string &config_json,
44 | bool *restart_required) override;
45 | Status SetState(const std::string &state_json) override;
46 |
47 | private:
48 | TempSensor *temp_sensor_;
49 | struct mgos_config_ts *cfg_;
50 |
51 | mgos::hap::FloatCharacteristic *current_temperature_characteristic_;
52 |
53 | void ValueChanged();
54 | };
55 |
56 | void CreateHAPTemperatureSensor(
57 | int id, TempSensor *sensor, const struct mgos_config_ts *ts_cfg,
58 | std::vector> *comps,
59 | std::vector> *accs,
60 | HAPAccessoryServerRef *svr);
61 |
62 | } // namespace hap
63 | } // namespace shelly
64 |
--------------------------------------------------------------------------------
/src/shelly_hap_valve.hpp:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) Shelly-HomeKit Contributors
3 | * All rights reserved
4 | *
5 | * Licensed under the Apache License, Version 2.0 (the "License");
6 | * you may not use this file except in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | */
17 |
18 | #pragma once
19 |
20 | #include "mgos_hap_chars.hpp"
21 | #include "shelly_switch.hpp"
22 |
23 | namespace shelly {
24 | namespace hap {
25 |
26 | class Valve : public ShellySwitch {
27 | public:
28 | Valve(int id, Input *in, Output *out, PowerMeter *out_pm, Output *led_out,
29 | struct mgos_config_sw *cfg);
30 | virtual ~Valve();
31 |
32 | Status Init() override;
33 | };
34 |
35 | } // namespace hap
36 | } // namespace shelly
37 |
--------------------------------------------------------------------------------
/src/shelly_input.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) Shelly-HomeKit Contributors
3 | * All rights reserved
4 | *
5 | * Licensed under the Apache License, Version 2.0 (the "License");
6 | * you may not use this file except in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | */
17 |
18 | #include "shelly_input.hpp"
19 |
20 | namespace shelly {
21 |
22 | // static
23 | constexpr Input::HandlerID Input::kInvalidHandlerID;
24 |
25 | Input::Input(int id) : id_(id) {
26 | }
27 |
28 | Input::~Input() {
29 | }
30 |
31 | // static
32 | const char *Input::EventName(Event ev) {
33 | switch (ev) {
34 | case Event::kChange:
35 | return "change";
36 | case Event::kSingle:
37 | return "single";
38 | case Event::kDouble:
39 | return "double";
40 | case Event::kLong:
41 | return "long";
42 | case Event::kReset:
43 | return "reset";
44 | case Event::kMax:
45 | break;
46 | }
47 | return "";
48 | }
49 |
50 | int Input::id() const {
51 | return id_;
52 | }
53 |
54 | Input::HandlerID Input::AddHandler(HandlerFn h) {
55 | int i;
56 | for (i = 0; i < (int) handlers_.size(); i++) {
57 | if (handlers_[i] == nullptr) {
58 | handlers_[i] = h;
59 | return i;
60 | }
61 | }
62 | handlers_.push_back(h);
63 | return i;
64 | }
65 |
66 | void Input::RemoveHandler(HandlerID hi) {
67 | if (hi < 0) return;
68 | handlers_[hi] = nullptr;
69 | }
70 |
71 | void Input::InjectEvent(Event ev, bool state) {
72 | CallHandlers(ev, state, true /* injected */);
73 | }
74 |
75 | void Input::CallHandlers(Event ev, bool state, bool injected) {
76 | LOG(LL_INFO, ("Input %d: %s (state %d)%s", id(), EventName(ev), state,
77 | (injected ? " [injected]" : "")));
78 | for (auto &h : handlers_) {
79 | if (h != nullptr) h(ev, state);
80 | }
81 | }
82 |
83 | } // namespace shelly
84 |
--------------------------------------------------------------------------------
/src/shelly_input.hpp:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) Shelly-HomeKit Contributors
3 | * All rights reserved
4 | *
5 | * Licensed under the Apache License, Version 2.0 (the "License");
6 | * you may not use this file except in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | */
17 |
18 | #pragma once
19 |
20 | #include
21 |
22 | #include "shelly_common.hpp"
23 |
24 | namespace shelly {
25 |
26 | class Input {
27 | public:
28 | enum class Event {
29 | kChange = 0,
30 | kSingle = 1,
31 | kDouble = 2,
32 | kLong = 3,
33 | kReset = 4,
34 | kMax,
35 | };
36 | explicit Input(int id);
37 | virtual ~Input();
38 |
39 | static const char *EventName(Event ev);
40 |
41 | int id() const;
42 | virtual void Init() = 0;
43 | virtual bool GetState() = 0;
44 | virtual void SetInvert(bool invert) = 0;
45 |
46 | typedef int HandlerID;
47 | static constexpr HandlerID kInvalidHandlerID = -1;
48 | typedef std::function HandlerFn;
49 | HandlerID AddHandler(HandlerFn h);
50 | void RemoveHandler(HandlerID hi);
51 |
52 | void InjectEvent(Event ev, bool state);
53 |
54 | protected:
55 | void CallHandlers(Event ev, bool state, bool injected = false);
56 |
57 | private:
58 | const int id_;
59 | std::vector handlers_;
60 |
61 | Input(const Input &other) = delete;
62 | };
63 |
64 | } // namespace shelly
65 |
--------------------------------------------------------------------------------
/src/shelly_input_pin.hpp:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) Shelly-HomeKit Contributors
3 | * All rights reserved
4 | *
5 | * Licensed under the Apache License, Version 2.0 (the "License");
6 | * you may not use this file except in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | */
17 |
18 | #pragma once
19 |
20 | #include "shelly_input.hpp"
21 |
22 | #include "mgos_gpio.h"
23 | #include "mgos_timers.hpp"
24 |
25 | namespace shelly {
26 |
27 | class InputPin : public Input {
28 | public:
29 | static constexpr int kDefaultShortPressDurationMs = 500;
30 | static constexpr int kDefaultLongPressDurationMs = 1000;
31 |
32 | struct Config {
33 | int pin;
34 | int on_value;
35 | enum mgos_gpio_pull_type pull;
36 | bool enable_reset;
37 | int short_press_duration_ms;
38 | int long_press_duration_ms;
39 | };
40 |
41 | InputPin(int id, int pin, int on_value, enum mgos_gpio_pull_type pull,
42 | bool enable_reset);
43 | InputPin(int id, const Config &cfg);
44 | virtual ~InputPin();
45 |
46 | // Input interface impl.
47 | bool GetState() override;
48 | virtual void Init() override;
49 | void SetInvert(bool invert) override;
50 |
51 | protected:
52 | virtual bool ReadPin();
53 | void HandleGPIOInt();
54 |
55 | const Config cfg_;
56 | bool invert_ = false;
57 |
58 | private:
59 | enum class State {
60 | kIdle = 0,
61 | kWaitOffSingle = 1,
62 | kWaitOnDouble = 2,
63 | kWaitOffDouble = 3,
64 | kWaitOffLong = 4,
65 | };
66 |
67 | static void GPIOIntHandler(int pin, void *arg);
68 |
69 | void DetectReset(double now, bool cur_state);
70 |
71 | void HandleTimer();
72 |
73 | bool last_state_ = false;
74 | int change_cnt_ = 0; // State change counter for reset.
75 | double last_change_ts_ = 0; // Timestamp of last change (uptime).
76 |
77 | State state_ = State::kIdle;
78 | int timer_cnt_ = 0;
79 | mgos::Timer timer_;
80 |
81 | InputPin(const InputPin &other) = delete;
82 | };
83 |
84 | } // namespace shelly
85 |
--------------------------------------------------------------------------------
/src/shelly_light_bulb_controller.hpp:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) Shelly-HomeKit Contributors
3 | * All rights reserved
4 | *
5 | * Licensed under the Apache License, Version 2.0 (the "License");
6 | * you may not use this file except in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | */
17 |
18 | #pragma once
19 |
20 | #include
21 | #include
22 |
23 | #include "mgos_sys_config.h"
24 | #include "mgos_timers.hpp"
25 |
26 | #include "shelly_common.hpp"
27 |
28 | namespace shelly {
29 |
30 | class LightBulbControllerBase {
31 | public:
32 | enum class BulbType {
33 | kWhite = 0,
34 | kCCT = 1,
35 | kRGBW = 2,
36 | kMax = 3,
37 | };
38 | typedef std::function
40 | UpdateFn;
41 |
42 | LightBulbControllerBase(struct mgos_config_lb *cfg, UpdateFn ud);
43 | LightBulbControllerBase(const LightBulbControllerBase &other) = delete;
44 | virtual ~LightBulbControllerBase();
45 |
46 | void UpdateOutput(struct mgos_config_lb *cfg, bool cancel_previous) const;
47 |
48 | virtual BulbType Type() = 0;
49 |
50 | bool IsOn() const;
51 | bool IsOff() const;
52 |
53 | protected:
54 | struct mgos_config_lb *cfg_;
55 | const UpdateFn update_;
56 | };
57 |
58 | template
59 | struct Transition {
60 | T state_end;
61 | int64_t transition_time_micros = 0;
62 | };
63 |
64 | template
65 | class LightBulbController : public LightBulbControllerBase {
66 | public:
67 | LightBulbController(struct mgos_config_lb *cfg)
68 | : LightBulbControllerBase(
69 | cfg, std::bind(&LightBulbController::UpdateOutputSpecialized,
70 | this, _1, _2)),
71 | transition_timer_(
72 | std::bind(&LightBulbController::TransitionTimerCB, this)) {
73 | }
74 | LightBulbController(const LightBulbControllerBase &other) = delete;
75 |
76 | private:
77 | mgos::Timer transition_timer_;
78 | int64_t transition_start_ = 0;
79 |
80 | T state_start_{};
81 | T state_now_{};
82 |
83 | std::deque> transitions_;
84 |
85 | virtual T ConfigToState(const struct mgos_config_lb &cfg) const = 0;
86 | virtual void ReportTransition(const T &next, const T &prev) = 0;
87 | virtual void UpdatePWM(const T &state) = 0;
88 |
89 | void StartPendingTransitions();
90 | void TransitionTimerCB();
91 | void UpdateOutputSpecialized(const struct mgos_config_lb &cfg,
92 | bool cancel_previous);
93 | };
94 | } // namespace shelly
95 |
--------------------------------------------------------------------------------
/src/shelly_main.hpp:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) Shelly-HomeKit Contributors
3 | * All rights reserved
4 | *
5 | * Licensed under the Apache License, Version 2.0 (the "License");
6 | * you may not use this file except in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | */
17 |
18 | #pragma once
19 |
20 | #include
21 | #include
22 |
23 | #include "mgos_sys_config.h"
24 |
25 | #include "mgos_hap_accessory.hpp"
26 | #include "mgos_hap_service.hpp"
27 | #include "shelly_component.hpp"
28 | #include "shelly_input.hpp"
29 | #include "shelly_output.hpp"
30 | #include "shelly_pm.hpp"
31 | #include "shelly_reset.hpp"
32 | #include "shelly_temp_sensor.hpp"
33 |
34 | #define AUTH_USER "admin"
35 | #define AUTH_FILE_NAME "passwd256"
36 | #define ACL_FILE_NAME "rpc_acl.json"
37 | #define KVS_FILE_NAME "kvs.json"
38 |
39 | namespace shelly {
40 |
41 | extern std::vector> g_comps;
42 |
43 | bool DetectAddon(int pin_in, int pin_out);
44 | void RestoreUART();
45 | Input *FindInput(int id);
46 | Output *FindOutput(int id);
47 | PowerMeter *FindPM(int id);
48 |
49 | void CreateHAPSensors(std::vector> *sensors,
50 | std::vector> *comps,
51 | std::vector> *accs,
52 | HAPAccessoryServerRef *svr);
53 |
54 | void CreateHAPSwitch(int id, const struct mgos_config_sw *sw_cfg,
55 | const struct mgos_config_in *in_cfg,
56 | std::vector> *comps,
57 | std::vector> *accs,
58 | HAPAccessoryServerRef *svr, bool to_pri_acc,
59 | Output *led_out = nullptr);
60 |
61 | void HandleInputResetSequence(Input *in, int out_gpio, Input::Event ev,
62 | bool cur_state);
63 |
64 | void StopService();
65 | void RestartService();
66 | bool IsServiceRunning();
67 | bool IsPaired();
68 |
69 | bool AllComponentsIdle();
70 |
71 | StatusOr GetSystemTemperature();
72 |
73 | #define SHELLY_SERVICE_FLAG_UPDATE (1 << 0)
74 | #define SHELLY_SERVICE_FLAG_REBOOT (1 << 1)
75 | #define SHELLY_SERVICE_FLAG_OVERHEAT (1 << 2)
76 | #define SHELLY_SERVICE_FLAG_REVERT (1 << 3)
77 | uint8_t GetServiceFlags();
78 | void SetServiceFlags(uint8_t flags);
79 | void ClearServiceFlags(uint8_t flags);
80 |
81 | mgos::hap::Accessory::IdentifyCB GetIdentifyCB();
82 | void SetIdentifyCB(mgos::hap::Accessory::IdentifyCB cb);
83 |
84 | // Implemented for each model.
85 |
86 | void CreatePeripherals(std::vector> *inputs,
87 | std::vector> *outputs,
88 | std::vector> *pms,
89 | std::unique_ptr *sys_temp);
90 |
91 | void CreateComponents(std::vector> *comps,
92 | std::vector> *accs,
93 | HAPAccessoryServerRef *svr);
94 |
95 | } // namespace shelly
96 |
--------------------------------------------------------------------------------
/src/shelly_noisy_input_pin.hpp:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) Shelly-HomeKit Contributors
3 | * All rights reserved
4 | *
5 | * Licensed under the Apache License, Version 2.0 (the "License");
6 | * you may not use this file except in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | */
17 |
18 | #pragma once
19 |
20 | #include "shelly_input_pin.hpp"
21 |
22 | namespace shelly {
23 |
24 | class NoisyInputPin : public InputPin {
25 | public:
26 | NoisyInputPin(int id, int pin, int on_value, enum mgos_gpio_pull_type pull,
27 | bool enable_reset);
28 | NoisyInputPin(int id, const InputPin::Config &cfg);
29 | virtual ~NoisyInputPin();
30 |
31 | void Init() override;
32 |
33 | void Check();
34 |
35 | private:
36 | bool ReadPin() override;
37 | };
38 |
39 | } // namespace shelly
40 |
--------------------------------------------------------------------------------
/src/shelly_ota.hpp:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) Shelly-HomeKit Contributors
3 | * All rights reserved
4 | *
5 | * Licensed under the Apache License, Version 2.0 (the "License");
6 | * you may not use this file except in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | */
17 |
18 | #pragma once
19 |
20 | #include
21 |
22 | #include "HAP.h"
23 |
24 | #include "shelly_common.hpp"
25 |
26 | namespace shelly {
27 |
28 | struct OTAProgress {
29 | std::string version;
30 | std::string build;
31 | int progress_pct = -1;
32 |
33 | OTAProgress() = default;
34 | OTAProgress(const std::string &version, const std::string &build);
35 | };
36 | StatusOr GetOTAProgress();
37 |
38 | void OTAInit(HAPAccessoryServerRef *server);
39 |
40 | } // namespace shelly
41 |
--------------------------------------------------------------------------------
/src/shelly_output.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) Shelly-HomeKit Contributors
3 | * All rights reserved
4 | *
5 | * Licensed under the Apache License, Version 2.0 (the "License");
6 | * you may not use this file except in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | */
17 |
18 | #include "shelly_output.hpp"
19 |
20 | #include "mgos.hpp"
21 | #include "mgos_gpio.h"
22 |
23 | #if CS_PLATFORM != CS_P_ESP8266
24 | #include "driver/gpio.h"
25 | #endif
26 |
27 | #ifdef MGOS_HAVE_PWM
28 | #include "mgos_pwm.h"
29 | #endif
30 |
31 | namespace shelly {
32 |
33 | Output::Output(int id) : id_(id) {
34 | }
35 |
36 | Output::~Output() {
37 | }
38 |
39 | int Output::id() const {
40 | return id_;
41 | }
42 |
43 | OutputPin::OutputPin(int id, int pin, int on_value)
44 | : Output(id),
45 | pin_(pin),
46 | on_value_(on_value),
47 | pulse_timer_(std::bind(&OutputPin::PulseTimerCB, this)) {
48 | mgos_gpio_set_mode(pin_, MGOS_GPIO_MODE_OUTPUT);
49 | #if CS_PLATFORM != CS_P_ESP8266
50 | gpio_hold_dis((gpio_num_t) pin);
51 | #endif
52 | LOG(LL_INFO, ("OutputPin %d: pin %d, on_value %d, state %s", id, pin,
53 | on_value, OnOff(GetState())));
54 | }
55 |
56 | OutputPin::~OutputPin() {
57 | #if CS_PLATFORM != CS_P_ESP8266
58 | gpio_hold_en((gpio_num_t) pin_);
59 | #endif
60 | }
61 |
62 | bool OutputPin::GetState() {
63 | return (mgos_gpio_read_out(pin_) == on_value_) ^ out_invert_;
64 | }
65 |
66 | int OutputPin::pin() const {
67 | return pin_;
68 | }
69 |
70 | Status OutputPin::SetState(bool on, const char *source) {
71 | bool cur_state = GetState();
72 | mgos_gpio_write(pin_, ((on ^ out_invert_) ? on_value_ : !on_value_));
73 | pulse_active_ = false;
74 | if (on == cur_state) return Status::OK();
75 | if (source == nullptr) source = "";
76 | LOG(LL_INFO,
77 | ("Output %d: %s -> %s (%s)", id(), OnOff(cur_state), OnOff(on), source));
78 | return Status::OK();
79 | }
80 |
81 | Status OutputPin::SetStatePWM(float duty, const char *source) {
82 | #ifdef MGOS_HAVE_PWM
83 | LOG(LL_INFO, ("Duty: %.3f", duty));
84 | if (duty == 0) {
85 | mgos_pwm_set(pin_, 0, 0);
86 | }
87 | #if CS_PLATFORM == CS_P_ESP8266
88 | else if (duty == 1) {
89 | mgos_gpio_write(pin_, 1);
90 | LOG(LL_INFO,
91 | ("Output %d: %s (%s)", id(), (duty == 0 ? "OFF" : "ON"), source));
92 | }
93 | #endif
94 | else {
95 | mgos_pwm_set(pin_, 400, duty);
96 | LOG(LL_INFO, ("Output %d: %f (%s)", id(), duty, source));
97 | }
98 | return Status::OK();
99 | #else
100 | (void) duty;
101 | (void) source;
102 | return Status::UNIMPLEMENTED();
103 | #endif
104 | }
105 |
106 | Status OutputPin::Pulse(bool on, int duration_ms, const char *source) {
107 | Status st = SetState(on, source);
108 | if (!st.ok()) return st;
109 | pulse_timer_.Reset(duration_ms, 0);
110 | pulse_active_ = true;
111 | return Status::OK();
112 | }
113 |
114 | void OutputPin::PulseTimerCB() {
115 | if (!pulse_active_) return;
116 | SetState(!GetState(), "pulse_off");
117 | }
118 |
119 | void OutputPin::SetInvert(bool out_invert) {
120 | out_invert_ = out_invert;
121 | GetState();
122 | }
123 |
124 | } // namespace shelly
125 |
--------------------------------------------------------------------------------
/src/shelly_output.hpp:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) Shelly-HomeKit Contributors
3 | * All rights reserved
4 | *
5 | * Licensed under the Apache License, Version 2.0 (the "License");
6 | * you may not use this file except in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | */
17 |
18 | #pragma once
19 |
20 | #include "shelly_common.hpp"
21 |
22 | #include "mgos_timers.hpp"
23 |
24 | namespace shelly {
25 |
26 | class Output {
27 | public:
28 | explicit Output(int id);
29 | virtual ~Output();
30 |
31 | int id() const;
32 | virtual bool GetState() = 0;
33 | virtual Status SetState(bool on, const char *source) = 0;
34 | virtual Status SetStatePWM(float duty, const char *source) = 0;
35 | virtual Status Pulse(bool on, int duration_ms, const char *source) = 0;
36 | virtual void SetInvert(bool out_invert) = 0;
37 |
38 | private:
39 | const int id_;
40 | Output(const Output &other) = delete;
41 | };
42 |
43 | class OutputPin : public Output {
44 | public:
45 | OutputPin(int id, int pin, int on_value);
46 | virtual ~OutputPin();
47 |
48 | // Output interface impl.
49 | bool GetState() override;
50 | Status SetState(bool on, const char *source) override;
51 | Status SetStatePWM(float duty, const char *source) override;
52 | Status Pulse(bool on, int duration_ms, const char *source) override;
53 | int pin() const;
54 | void SetInvert(bool out_invert) override;
55 |
56 | protected:
57 | bool out_invert_ = false;
58 |
59 | private:
60 | void PulseTimerCB();
61 |
62 | const int pin_;
63 | const int on_value_;
64 |
65 | bool pulse_active_ = false;
66 | mgos::Timer pulse_timer_;
67 |
68 | OutputPin(const OutputPin &other) = delete;
69 | };
70 |
71 | } // namespace shelly
72 |
--------------------------------------------------------------------------------
/src/shelly_pm.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) Shelly-HomeKit Contributors
3 | * All rights reserved
4 | *
5 | * Licensed under the Apache License, Version 2.0 (the "License");
6 | * you may not use this file except in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | */
17 |
18 | #include "shelly_pm.hpp"
19 |
20 | namespace shelly {
21 |
22 | PowerMeter::PowerMeter(int id) : id_(id) {
23 | }
24 |
25 | PowerMeter::~PowerMeter() {
26 | }
27 |
28 | int PowerMeter::id() const {
29 | return id_;
30 | }
31 |
32 | } // namespace shelly
33 |
--------------------------------------------------------------------------------
/src/shelly_pm.hpp:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) Shelly-HomeKit Contributors
3 | * All rights reserved
4 | *
5 | * Licensed under the Apache License, Version 2.0 (the "License");
6 | * you may not use this file except in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | */
17 |
18 | #pragma once
19 |
20 | #include
21 | #include
22 |
23 | #include "shelly_common.hpp"
24 |
25 | namespace shelly {
26 |
27 | class PowerMeter {
28 | public:
29 | explicit PowerMeter(int id);
30 | virtual ~PowerMeter();
31 |
32 | int id() const;
33 |
34 | virtual Status Init() = 0;
35 | virtual StatusOr