Compare commits
11 Commits
81b1aeed03
...
master
Author | SHA1 | Date | |
---|---|---|---|
b9e92cd46e | |||
23e5caf13a | |||
565dac1946 | |||
a8499a27b2 | |||
bedd9c3011 | |||
fd7e0df860 | |||
86a830897f | |||
058e57e1f5 | |||
a74469bb2e | |||
f7a842a7c1 | |||
c92ed75f06 |
312
README.md
312
README.md
@@ -60,7 +60,7 @@ and [my update post on version 2.0](https://www.boniface.me/posts/the-supersenso
|
|||||||
|-------|--------------------|----------------------------------|-------|
|
|-------|--------------------|----------------------------------|-------|
|
||||||
| 1 | GY-SGP41 | $11.08 | [AliExpress](https://www.aliexpress.com/item/1005006746827606.html) |
|
| 1 | GY-SGP41 | $11.08 | [AliExpress](https://www.aliexpress.com/item/1005006746827606.html) |
|
||||||
| 1 | GY-SHT45 | $5.67 | [AliExpress](https://www.aliexpress.com/item/1005008175340220.html)* |
|
| 1 | GY-SHT45 | $5.67 | [AliExpress](https://www.aliexpress.com/item/1005008175340220.html)* |
|
||||||
| 1 | AM312 | $0.81 | [AliExpress](https://www.aliexpress.com/item/1005001572550300.html) |
|
| 1 | AM312 | $1.97 | [AliExpress](https://www.aliexpress.com/item/1005008067324301.html) |
|
||||||
| 1 | TSL2591 | $4.59 | [AliExpress](https://www.aliexpress.com/item/1005008619462097.html) |
|
| 1 | TSL2591 | $4.59 | [AliExpress](https://www.aliexpress.com/item/1005008619462097.html) |
|
||||||
| 1 | HL-LD2510C | $4.79 | [AliExpress](https://www.aliexpress.com/item/1005006000579211.html)* |
|
| 1 | HL-LD2510C | $4.79 | [AliExpress](https://www.aliexpress.com/item/1005006000579211.html)* |
|
||||||
| 1 | INMP441 | $2.93 | [AliExpress](https://www.aliexpress.com/item/1005002902615623.html) |
|
| 1 | INMP441 | $2.93 | [AliExpress](https://www.aliexpress.com/item/1005002902615623.html) |
|
||||||
@@ -69,7 +69,7 @@ and [my update post on version 2.0](https://www.boniface.me/posts/the-supersenso
|
|||||||
| 1 | 470Ω resistor | $0.08 ($7.99/100) | [Amazon](https://www.amazon.ca/dp/B08MKQX2XT) |
|
| 1 | 470Ω resistor | $0.08 ($7.99/100) | [Amazon](https://www.amazon.ca/dp/B08MKQX2XT) |
|
||||||
| 2 | Female pin header† | $1.59 ($15.99/10) | [Amazon](https://www.amazon.ca/dp/B08CMNRXJ1) |
|
| 2 | Female pin header† | $1.59 ($15.99/10) | [Amazon](https://www.amazon.ca/dp/B08CMNRXJ1) |
|
||||||
| 1 | Custom PCB (JLC) | $0.69 ($6.89/10) | [GitHub](https://github.com/joshuaboniface/supersensor) |
|
| 1 | Custom PCB (JLC) | $0.69 ($6.89/10) | [GitHub](https://github.com/joshuaboniface/supersensor) |
|
||||||
| **TOTAL** | | **$40.58** | |
|
| **TOTAL** | | **$41.74** | |
|
||||||
|
|
||||||
`*` Ensure you select the correct device on the page as it shows multiple options.
|
`*` Ensure you select the correct device on the page as it shows multiple options.
|
||||||
|
|
||||||
@@ -118,144 +118,7 @@ functionality, so I recommend using the provided models, but this is up to the b
|
|||||||
|
|
||||||
No other parts can be easily swapped without code or PCB design changes.
|
No other parts can be easily swapped without code or PCB design changes.
|
||||||
|
|
||||||
## Configurable Options
|
## Air Quality Handling
|
||||||
|
|
||||||
There are several UI-configurable options with the SuperSensor to help you
|
|
||||||
get the most out of the sensor for your particular use-case.
|
|
||||||
|
|
||||||
**Note:** Configuration of the LD2410C is excluded here, as it is extensively
|
|
||||||
configurable. See [the documentation](https://esphome.io/components/sensor/ld2410.html) for more details on its options.
|
|
||||||
|
|
||||||
### Enable Voice Support (switch)
|
|
||||||
|
|
||||||
If enabled (the default), the SuperSensor's voice functionality including
|
|
||||||
wake word will be started, or it can be disabled to use the SuperSensor
|
|
||||||
purely as a presence/environmental sensor.
|
|
||||||
|
|
||||||
### Enable Presence LED (switch)
|
|
||||||
|
|
||||||
If enabled (the default), when overall presence is detected, the LEDs will
|
|
||||||
glow "white" at 15% power to signal presence.
|
|
||||||
|
|
||||||
### Temperature Offset (selector, -30 to +10 @ 0.1, -5 default)
|
|
||||||
|
|
||||||
Allows calibration of the SHT45 temperature sensor with an offset from -30 to +10
|
|
||||||
degrees C. Useful if the sensor is misreporting actual ambient tempreatures. Due
|
|
||||||
to internal heating of the SHT45 by the ESP32, this defaults to -5; further
|
|
||||||
calibration may be needed for your sensors and environment based on an external
|
|
||||||
reference.
|
|
||||||
|
|
||||||
### Humidity Offset (selector, -20 to +20 @ 0.1)
|
|
||||||
|
|
||||||
Allows calibration of the SHT45 humidity sensor with an offset from -10 to +10
|
|
||||||
percent relative humidity. Useful if the sensor is misreporting actual humidity
|
|
||||||
based on an external reference.
|
|
||||||
|
|
||||||
### PIR Hold Time (selector, 0 to +60 @ 5, 0 default)
|
|
||||||
|
|
||||||
The SuperSensor uses an AM312 PIR sensor, which has a stock hold time of ~2.5
|
|
||||||
seconds. This setting allows increasing that value, with retrigger support, to
|
|
||||||
up to 60 seconds, allowing the PIR detection to report for longer. 0 represents
|
|
||||||
"as long as the AM312 fires".
|
|
||||||
|
|
||||||
### Light Threshold Control (selector, 0 to +200 @ 5, 30 default)
|
|
||||||
|
|
||||||
The SuperSensor features a "light presence" binary sensor based on the light
|
|
||||||
level reported by the TSL2591 sensor. This control defines the minimum lux
|
|
||||||
value from the sensor to be considered "presence". For instance, if you have
|
|
||||||
a room that is usually dark at 0-5 lux, but illuminated to 100 lux when a
|
|
||||||
(non-automated) light switch is turned on, you could set a threshold here
|
|
||||||
of say 30 lux: then, while the light is on, "light presence" is detected,
|
|
||||||
and when the light is off, "light presence" is cleared. Light presence can
|
|
||||||
be used standalone or as part of the integrated occupancy sensor (below).
|
|
||||||
|
|
||||||
### Integrated Occupancy Sensor (Selector)
|
|
||||||
|
|
||||||
The SuperSensor features a fully integrated "occupancy" sensor, which can be
|
|
||||||
configured to provide exactly the sort of occupancy detection you may want
|
|
||||||
for your room.
|
|
||||||
|
|
||||||
There are 7 options (plus "None"/disabled), with both "detect" and "clear"
|
|
||||||
handled separately:
|
|
||||||
|
|
||||||
#### PIR + Radar + Light
|
|
||||||
|
|
||||||
Occupancy is detected when all 3 sensors report detected, and occupancy is
|
|
||||||
cleared when any of the sensors report cleared.
|
|
||||||
|
|
||||||
For detect, this provides the most "safety" against misfires, but requires
|
|
||||||
a normally-dark room with a non-automated light source and clear PIR
|
|
||||||
detection positioning.
|
|
||||||
|
|
||||||
For clear, this option is probably not very useful as it is likely to clear
|
|
||||||
quite frequently from the PIR, but is provided for completeness.
|
|
||||||
|
|
||||||
#### PIR + Radar
|
|
||||||
|
|
||||||
Occupancy is detected when both sensors report detected, and occupancy is
|
|
||||||
cleared when either of the sensors report cleared.
|
|
||||||
|
|
||||||
For detect, this provides good "safety" against PIR misfires without
|
|
||||||
needing a normally-dark room, though detection may be slightly delayed
|
|
||||||
from either sensor.
|
|
||||||
|
|
||||||
For clear, this option is probably not very useful as it is likely to clear
|
|
||||||
quite frequently from the PIR, but is provided for completeness.
|
|
||||||
|
|
||||||
#### PIR + Light
|
|
||||||
|
|
||||||
Occupancy is detected when both sensors report detected, and occupancy is
|
|
||||||
cleared when either of the sensors report cleared.
|
|
||||||
|
|
||||||
For detect, this provides some "safety" against PIR misfires, but requires
|
|
||||||
a normally-dark room with a non-automated light source and clear PIR
|
|
||||||
detection positioning.
|
|
||||||
|
|
||||||
For clear, this option is probably not very useful as it is likely to clear
|
|
||||||
quite frequently from the PIR, but is provided for completeness.
|
|
||||||
|
|
||||||
#### Radar + Light
|
|
||||||
|
|
||||||
Occupancy is detected when both sensors report detected, and occupancy is
|
|
||||||
cleared when either of the sensors report cleared.
|
|
||||||
|
|
||||||
For detect, this allows for radar detection while suppressing occupancy
|
|
||||||
without light, for instance in a hallway where one might not want a late
|
|
||||||
night bathroom visit to turn on the lights, or something to that effect.
|
|
||||||
|
|
||||||
For clear, this option can provide a useful option to clear presence
|
|
||||||
quickly if the lights go out, while still providing Radar presence.
|
|
||||||
|
|
||||||
#### PIR Only
|
|
||||||
|
|
||||||
Occupancy is based entirely on the PIR sensor for both detect and clear.
|
|
||||||
|
|
||||||
Prone to misfires, but otherwise a good option for quick detection and
|
|
||||||
clearance in a primarily-moving zone (e.g. hallway).
|
|
||||||
|
|
||||||
#### Radar Only
|
|
||||||
|
|
||||||
Occupancy is based entirely on the Radar sensor for both detect and clear.
|
|
||||||
|
|
||||||
Useful for an area with no consistent motion or light level.
|
|
||||||
|
|
||||||
#### Light Only
|
|
||||||
|
|
||||||
Occupancy is based entirely on the Light sensor for both detect and clear.
|
|
||||||
|
|
||||||
Useful for full dependence on an external light source.
|
|
||||||
|
|
||||||
#### None
|
|
||||||
|
|
||||||
Disable the functionality in either direction.
|
|
||||||
|
|
||||||
For detect, no occupancy will ever fire.
|
|
||||||
|
|
||||||
For clear, no states will clear occupancy; with any detect option, this
|
|
||||||
means that occupancy will be detected only once and never clear, which
|
|
||||||
is likely not useful.
|
|
||||||
|
|
||||||
## AQ Details
|
|
||||||
|
|
||||||
The SuperSensor 2.0 features an SGP41 air quality sensor by Sensirion. This is a powerful AQ
|
The SuperSensor 2.0 features an SGP41 air quality sensor by Sensirion. This is a powerful AQ
|
||||||
sensor which powers several commercial devices including the AirGradient One, which gave
|
sensor which powers several commercial devices including the AirGradient One, which gave
|
||||||
@@ -283,3 +146,172 @@ It also reacts strongly to heavy humidity, resulting in higher values in such en
|
|||||||
These should be used only as a general indication of air quality over short periods, rather
|
These should be used only as a general indication of air quality over short periods, rather
|
||||||
than an absolute reference over long periods (much to my own frustration but inevitable
|
than an absolute reference over long periods (much to my own frustration but inevitable
|
||||||
begruding acceptance).
|
begruding acceptance).
|
||||||
|
|
||||||
|
## Room Health
|
||||||
|
|
||||||
|
The SuperSensor 2.0 leverages the outputs of the SHT45 and SGP41 sensors to calculate a
|
||||||
|
"Room Health", expressed as a percentage, which represents how "healthy" i.e. comfortable
|
||||||
|
a room is for a person to be in.
|
||||||
|
|
||||||
|
The room health is calculated based on the VOC level, temperature, and relative humidity.
|
||||||
|
First, the raw value is converted to a per-sensor 100-0 scale as follows:
|
||||||
|
|
||||||
|
* For VOC levels, there is a set of linear scales based on common VOC level
|
||||||
|
mappings, such that less than 200 ppb is 100, 200-400 maps to 100-90,
|
||||||
|
400-600 maps to 90-70, 600-1500 maps to 70-40, 1500-3000 maps to 40-0, and
|
||||||
|
greater than 3000 is 0.
|
||||||
|
* For temperature and humidity, there is a single linear scale based on a
|
||||||
|
configurable penalty value, such that a value between the configurable
|
||||||
|
minimum and maximum is 100, and each degree C or %RH outside of that range
|
||||||
|
decreases the value by the penalty value.
|
||||||
|
|
||||||
|
Next, each indivdual per-sensor value is applied to the total 100-0 value by a configurable
|
||||||
|
weight, with the defaults being 40% to VOC level, 30% to temperature, and 30% to humidity. The
|
||||||
|
values can never total more than 100% or total to 0% but are otherwise normalized (i.e. decrease
|
||||||
|
others before increasing one, or the values will not be accepted; and at least one weight
|
||||||
|
must be >0).
|
||||||
|
|
||||||
|
The final result is thus a 100-0% range that, in broad strokes, describes the overall
|
||||||
|
health of the room. For some examples, assuming all of the default values below:
|
||||||
|
|
||||||
|
* Perfect: Temp 23C, humidity 50%RH, and VOC level 150ppb = 100% health
|
||||||
|
* A little warm: Temp 25C (+1), humidity 50%RH, and VOC level 250ppb = 97% health
|
||||||
|
* Dry: Temp 22C, humidity 30%RH (-10), VOC level 150ppb = 91% health
|
||||||
|
* Dirty air: Temp 23C, humidity 50%RH, VOC level 800ppb = 85% health
|
||||||
|
* Hot & humid: Temp 28C, humidity 70%RH, VOC level 250ppb = 84% health
|
||||||
|
* All-around bad: Temp 30C, humidity 30%RH, VOC level 2000ppb = 52% health
|
||||||
|
|
||||||
|
These are then mapped to textual values as well with the following bands:
|
||||||
|
|
||||||
|
* 100%-95%: Great
|
||||||
|
* 95%-90%: Good
|
||||||
|
* 90%-80%: Fair
|
||||||
|
* 80%-60%: Poor
|
||||||
|
* 60%-0%: Bad
|
||||||
|
|
||||||
|
As mentioned above, most portions of this are configurable; see the section below for
|
||||||
|
specific details of each configuration value.
|
||||||
|
|
||||||
|
## Configurable Options
|
||||||
|
|
||||||
|
There are several UI-configurable options with the SuperSensor to help you
|
||||||
|
get the most out of the sensor for your particular use-case.
|
||||||
|
|
||||||
|
**Note:** Configuration of the LD2410C is excluded here, as it is extensively
|
||||||
|
configurable. See [the documentation](https://esphome.io/components/sensor/ld2410.html) for more details on its options.
|
||||||
|
|
||||||
|
### Enable Voice Support (switch)
|
||||||
|
|
||||||
|
If enabled (the default), the SuperSensor's voice functionality including
|
||||||
|
wake word will be started, or it can be disabled to use the SuperSensor
|
||||||
|
purely as a presence/environmental sensor.
|
||||||
|
|
||||||
|
### Enable Presence LED (switch)
|
||||||
|
|
||||||
|
If enabled (the default), when overall presence is detected, the LEDs will
|
||||||
|
glow "white" at 15% power to signal presence.
|
||||||
|
|
||||||
|
### Temperature Offset (number, -30 to +10 @ 0.1, -5 default)
|
||||||
|
|
||||||
|
Allows calibration of the SHT45 temperature sensor with an offset from -30 to +10
|
||||||
|
degrees C. Useful if the sensor is misreporting actual ambient tempreatures. Due
|
||||||
|
to internal heating of the SHT45 by the ESP32, this defaults to -5; further
|
||||||
|
calibration may be needed for your sensors and environment based on an external
|
||||||
|
reference.
|
||||||
|
|
||||||
|
### Humidity Offset (number, -20 to +20 @ 0.1)
|
||||||
|
|
||||||
|
Allows calibration of the SHT45 humidity sensor with an offset from -10 to +10
|
||||||
|
percent relative humidity. Useful if the sensor is misreporting actual humidity
|
||||||
|
based on an external reference.
|
||||||
|
|
||||||
|
### PIR Hold Time (number, 0 to +60 @ 5, 0 default)
|
||||||
|
|
||||||
|
The SuperSensor uses an AM312 PIR sensor, which has a stock hold time of ~2.5
|
||||||
|
seconds. This setting allows increasing that value, with retrigger support, to
|
||||||
|
up to 60 seconds, allowing the PIR detection to report for longer. 0 represents
|
||||||
|
"as long as the AM312 fires".
|
||||||
|
|
||||||
|
### Light Threshold Control (number, 0 to +200 @ 5, 30 default)
|
||||||
|
|
||||||
|
The SuperSensor features a "light presence" binary sensor based on the light
|
||||||
|
level reported by the TSL2591 sensor. This control defines the minimum lux
|
||||||
|
value from the sensor to be considered "presence". For instance, if you have
|
||||||
|
a room that is usually dark at 0-5 lux, but illuminated to 100 lux when a
|
||||||
|
(non-automated) light switch is turned on, you could set a threshold here
|
||||||
|
of say 30 lux: then, while the light is on, "light presence" is detected,
|
||||||
|
and when the light is off, "light presence" is cleared. Light presence can
|
||||||
|
be used standalone or as part of the integrated occupancy sensor (below).
|
||||||
|
|
||||||
|
### Integrated Occupancy Sensor (selector)
|
||||||
|
|
||||||
|
The SuperSensor features a fully integrated "occupancy" sensor, which can be
|
||||||
|
configured to provide exactly the sort of occupancy detection you may want
|
||||||
|
for your room.
|
||||||
|
|
||||||
|
There are 7 options (plus "None"/disabled), with both "detect" and "clear"
|
||||||
|
handled separately. Occupancy is always detected when ALL of the selected
|
||||||
|
sensors report detection, and occupancy is always cleared when ANY of the
|
||||||
|
selected sensors stop reporting detection (logical AND in, logical OR out).
|
||||||
|
|
||||||
|
* PIR + Radar + Light
|
||||||
|
* PIR + Radar
|
||||||
|
* PIR + Light
|
||||||
|
* Radar + Light
|
||||||
|
* PIR Only
|
||||||
|
* Radar Only
|
||||||
|
* Light Only
|
||||||
|
* None
|
||||||
|
|
||||||
|
### Room Health Sensor
|
||||||
|
|
||||||
|
#### Minimum Temperature (number, 15 to 30 @ 0.5, 21 default)
|
||||||
|
|
||||||
|
The lower bounds of a fully comfortable temperature; temperature values below
|
||||||
|
this value will begin decreasing the room health score.
|
||||||
|
|
||||||
|
#### Maximum Temperature (number, 15 to 30 @ 0.5, 24 default)
|
||||||
|
|
||||||
|
The upper bounds of a fully comfortable temperature; temperature values above
|
||||||
|
this value will begin decreasing the room health score.
|
||||||
|
|
||||||
|
#### Temperature Penalty (number, 1 to 20 @ 1, 10 default)
|
||||||
|
|
||||||
|
The penalty value per degree of temperature deviation from ideal levels, applied
|
||||||
|
to the pre-weighting value for temperature.
|
||||||
|
|
||||||
|
#### Minimum Humidity (number, 20 to 80 @ 1, 40 default)
|
||||||
|
|
||||||
|
The lower bounds of a fully comfortable relative humidity level; relative
|
||||||
|
humidity values below this value will begin decreasing the room health score.
|
||||||
|
|
||||||
|
#### Maximum Humidity (number, 20 to 80 @ 1, 60 default)
|
||||||
|
|
||||||
|
The upper bounds of a fully comfortable relative humidity level; relative
|
||||||
|
humidity values above this value will begin decreasing the room health score.
|
||||||
|
|
||||||
|
#### Humidity Penalty (number, 1 to 10 @ 1, 5 default)
|
||||||
|
|
||||||
|
The penalty value per % of relative humidity deviation from ideal levels, applied
|
||||||
|
to the pre-weighting value for humidity.
|
||||||
|
|
||||||
|
#### VOC Weight (number, 0.0 to 1.0, 0.4 default)
|
||||||
|
|
||||||
|
The weighting value of the VOC score relative to the other two for calculating
|
||||||
|
the total room health.
|
||||||
|
|
||||||
|
Note: Cannot exceed 0.4 without first decreasing one of the other weights (total max of 1.0).
|
||||||
|
|
||||||
|
#### Temperature Weight (number, 0.0 to 1.0, 0.3 default)
|
||||||
|
|
||||||
|
The weighting value of the Temperature score relative to the other two for
|
||||||
|
calculating the total room health.
|
||||||
|
|
||||||
|
Note: Cannot exceed 0.3 without first decreasing one of the other weights (total max of 1.0).
|
||||||
|
|
||||||
|
#### Humidity Weight (number, 0.0 to 1.0, 0.3 default)
|
||||||
|
|
||||||
|
The weighting value of the Humidity score relative to the other two for calculating
|
||||||
|
the total room health.
|
||||||
|
|
||||||
|
Note: Cannot exceed 0.3 without first decreasing one of the other weights (total max of 1.0).
|
||||||
|
BIN
case/.images/final-installation.jpg
Normal file
BIN
case/.images/final-installation.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 92 KiB |
427
case/LICENSE
Normal file
427
case/LICENSE
Normal file
@@ -0,0 +1,427 @@
|
|||||||
|
Attribution-ShareAlike 4.0 International
|
||||||
|
|
||||||
|
=======================================================================
|
||||||
|
|
||||||
|
Creative Commons Corporation ("Creative Commons") is not a law firm and
|
||||||
|
does not provide legal services or legal advice. Distribution of
|
||||||
|
Creative Commons public licenses does not create a lawyer-client or
|
||||||
|
other relationship. Creative Commons makes its licenses and related
|
||||||
|
information available on an "as-is" basis. Creative Commons gives no
|
||||||
|
warranties regarding its licenses, any material licensed under their
|
||||||
|
terms and conditions, or any related information. Creative Commons
|
||||||
|
disclaims all liability for damages resulting from their use to the
|
||||||
|
fullest extent possible.
|
||||||
|
|
||||||
|
Using Creative Commons Public Licenses
|
||||||
|
|
||||||
|
Creative Commons public licenses provide a standard set of terms and
|
||||||
|
conditions that creators and other rights holders may use to share
|
||||||
|
original works of authorship and other material subject to copyright
|
||||||
|
and certain other rights specified in the public license below. The
|
||||||
|
following considerations are for informational purposes only, are not
|
||||||
|
exhaustive, and do not form part of our licenses.
|
||||||
|
|
||||||
|
Considerations for licensors: Our public licenses are
|
||||||
|
intended for use by those authorized to give the public
|
||||||
|
permission to use material in ways otherwise restricted by
|
||||||
|
copyright and certain other rights. Our licenses are
|
||||||
|
irrevocable. Licensors should read and understand the terms
|
||||||
|
and conditions of the license they choose before applying it.
|
||||||
|
Licensors should also secure all rights necessary before
|
||||||
|
applying our licenses so that the public can reuse the
|
||||||
|
material as expected. Licensors should clearly mark any
|
||||||
|
material not subject to the license. This includes other CC-
|
||||||
|
licensed material, or material used under an exception or
|
||||||
|
limitation to copyright. More considerations for licensors:
|
||||||
|
wiki.creativecommons.org/Considerations_for_licensors
|
||||||
|
|
||||||
|
Considerations for the public: By using one of our public
|
||||||
|
licenses, a licensor grants the public permission to use the
|
||||||
|
licensed material under specified terms and conditions. If
|
||||||
|
the licensor's permission is not necessary for any reason--for
|
||||||
|
example, because of any applicable exception or limitation to
|
||||||
|
copyright--then that use is not regulated by the license. Our
|
||||||
|
licenses grant only permissions under copyright and certain
|
||||||
|
other rights that a licensor has authority to grant. Use of
|
||||||
|
the licensed material may still be restricted for other
|
||||||
|
reasons, including because others have copyright or other
|
||||||
|
rights in the material. A licensor may make special requests,
|
||||||
|
such as asking that all changes be marked or described.
|
||||||
|
Although not required by our licenses, you are encouraged to
|
||||||
|
respect those requests where reasonable. More considerations
|
||||||
|
for the public:
|
||||||
|
wiki.creativecommons.org/Considerations_for_licensees
|
||||||
|
|
||||||
|
=======================================================================
|
||||||
|
|
||||||
|
Creative Commons Attribution-ShareAlike 4.0 International Public
|
||||||
|
License
|
||||||
|
|
||||||
|
By exercising the Licensed Rights (defined below), You accept and agree
|
||||||
|
to be bound by the terms and conditions of this Creative Commons
|
||||||
|
Attribution-ShareAlike 4.0 International Public License ("Public
|
||||||
|
License"). To the extent this Public License may be interpreted as a
|
||||||
|
contract, You are granted the Licensed Rights in consideration of Your
|
||||||
|
acceptance of these terms and conditions, and the Licensor grants You
|
||||||
|
such rights in consideration of benefits the Licensor receives from
|
||||||
|
making the Licensed Material available under these terms and
|
||||||
|
conditions.
|
||||||
|
|
||||||
|
|
||||||
|
Section 1 -- Definitions.
|
||||||
|
|
||||||
|
a. Adapted Material means material subject to Copyright and Similar
|
||||||
|
Rights that is derived from or based upon the Licensed Material
|
||||||
|
and in which the Licensed Material is translated, altered,
|
||||||
|
arranged, transformed, or otherwise modified in a manner requiring
|
||||||
|
permission under the Copyright and Similar Rights held by the
|
||||||
|
Licensor. For purposes of this Public License, where the Licensed
|
||||||
|
Material is a musical work, performance, or sound recording,
|
||||||
|
Adapted Material is always produced where the Licensed Material is
|
||||||
|
synched in timed relation with a moving image.
|
||||||
|
|
||||||
|
b. Adapter's License means the license You apply to Your Copyright
|
||||||
|
and Similar Rights in Your contributions to Adapted Material in
|
||||||
|
accordance with the terms and conditions of this Public License.
|
||||||
|
|
||||||
|
c. BY-SA Compatible License means a license listed at
|
||||||
|
creativecommons.org/compatiblelicenses, approved by Creative
|
||||||
|
Commons as essentially the equivalent of this Public License.
|
||||||
|
|
||||||
|
d. Copyright and Similar Rights means copyright and/or similar rights
|
||||||
|
closely related to copyright including, without limitation,
|
||||||
|
performance, broadcast, sound recording, and Sui Generis Database
|
||||||
|
Rights, without regard to how the rights are labeled or
|
||||||
|
categorized. For purposes of this Public License, the rights
|
||||||
|
specified in Section 2(b)(1)-(2) are not Copyright and Similar
|
||||||
|
Rights.
|
||||||
|
|
||||||
|
e. Effective Technological Measures means those measures that, in the
|
||||||
|
absence of proper authority, may not be circumvented under laws
|
||||||
|
fulfilling obligations under Article 11 of the WIPO Copyright
|
||||||
|
Treaty adopted on December 20, 1996, and/or similar international
|
||||||
|
agreements.
|
||||||
|
|
||||||
|
f. Exceptions and Limitations means fair use, fair dealing, and/or
|
||||||
|
any other exception or limitation to Copyright and Similar Rights
|
||||||
|
that applies to Your use of the Licensed Material.
|
||||||
|
|
||||||
|
g. License Elements means the license attributes listed in the name
|
||||||
|
of a Creative Commons Public License. The License Elements of this
|
||||||
|
Public License are Attribution and ShareAlike.
|
||||||
|
|
||||||
|
h. Licensed Material means the artistic or literary work, database,
|
||||||
|
or other material to which the Licensor applied this Public
|
||||||
|
License.
|
||||||
|
|
||||||
|
i. Licensed Rights means the rights granted to You subject to the
|
||||||
|
terms and conditions of this Public License, which are limited to
|
||||||
|
all Copyright and Similar Rights that apply to Your use of the
|
||||||
|
Licensed Material and that the Licensor has authority to license.
|
||||||
|
|
||||||
|
j. Licensor means the individual(s) or entity(ies) granting rights
|
||||||
|
under this Public License.
|
||||||
|
|
||||||
|
k. Share means to provide material to the public by any means or
|
||||||
|
process that requires permission under the Licensed Rights, such
|
||||||
|
as reproduction, public display, public performance, distribution,
|
||||||
|
dissemination, communication, or importation, and to make material
|
||||||
|
available to the public including in ways that members of the
|
||||||
|
public may access the material from a place and at a time
|
||||||
|
individually chosen by them.
|
||||||
|
|
||||||
|
l. Sui Generis Database Rights means rights other than copyright
|
||||||
|
resulting from Directive 96/9/EC of the European Parliament and of
|
||||||
|
the Council of 11 March 1996 on the legal protection of databases,
|
||||||
|
as amended and/or succeeded, as well as other essentially
|
||||||
|
equivalent rights anywhere in the world.
|
||||||
|
|
||||||
|
m. You means the individual or entity exercising the Licensed Rights
|
||||||
|
under this Public License. Your has a corresponding meaning.
|
||||||
|
|
||||||
|
|
||||||
|
Section 2 -- Scope.
|
||||||
|
|
||||||
|
a. License grant.
|
||||||
|
|
||||||
|
1. Subject to the terms and conditions of this Public License,
|
||||||
|
the Licensor hereby grants You a worldwide, royalty-free,
|
||||||
|
non-sublicensable, non-exclusive, irrevocable license to
|
||||||
|
exercise the Licensed Rights in the Licensed Material to:
|
||||||
|
|
||||||
|
a. reproduce and Share the Licensed Material, in whole or
|
||||||
|
in part; and
|
||||||
|
|
||||||
|
b. produce, reproduce, and Share Adapted Material.
|
||||||
|
|
||||||
|
2. Exceptions and Limitations. For the avoidance of doubt, where
|
||||||
|
Exceptions and Limitations apply to Your use, this Public
|
||||||
|
License does not apply, and You do not need to comply with
|
||||||
|
its terms and conditions.
|
||||||
|
|
||||||
|
3. Term. The term of this Public License is specified in Section
|
||||||
|
6(a).
|
||||||
|
|
||||||
|
4. Media and formats; technical modifications allowed. The
|
||||||
|
Licensor authorizes You to exercise the Licensed Rights in
|
||||||
|
all media and formats whether now known or hereafter created,
|
||||||
|
and to make technical modifications necessary to do so. The
|
||||||
|
Licensor waives and/or agrees not to assert any right or
|
||||||
|
authority to forbid You from making technical modifications
|
||||||
|
necessary to exercise the Licensed Rights, including
|
||||||
|
technical modifications necessary to circumvent Effective
|
||||||
|
Technological Measures. For purposes of this Public License,
|
||||||
|
simply making modifications authorized by this Section 2(a)
|
||||||
|
(4) never produces Adapted Material.
|
||||||
|
|
||||||
|
5. Downstream recipients.
|
||||||
|
|
||||||
|
a. Offer from the Licensor -- Licensed Material. Every
|
||||||
|
recipient of the Licensed Material automatically
|
||||||
|
receives an offer from the Licensor to exercise the
|
||||||
|
Licensed Rights under the terms and conditions of this
|
||||||
|
Public License.
|
||||||
|
|
||||||
|
b. Additional offer from the Licensor -- Adapted Material.
|
||||||
|
Every recipient of Adapted Material from You
|
||||||
|
automatically receives an offer from the Licensor to
|
||||||
|
exercise the Licensed Rights in the Adapted Material
|
||||||
|
under the conditions of the Adapter's License You apply.
|
||||||
|
|
||||||
|
c. No downstream restrictions. You may not offer or impose
|
||||||
|
any additional or different terms or conditions on, or
|
||||||
|
apply any Effective Technological Measures to, the
|
||||||
|
Licensed Material if doing so restricts exercise of the
|
||||||
|
Licensed Rights by any recipient of the Licensed
|
||||||
|
Material.
|
||||||
|
|
||||||
|
6. No endorsement. Nothing in this Public License constitutes or
|
||||||
|
may be construed as permission to assert or imply that You
|
||||||
|
are, or that Your use of the Licensed Material is, connected
|
||||||
|
with, or sponsored, endorsed, or granted official status by,
|
||||||
|
the Licensor or others designated to receive attribution as
|
||||||
|
provided in Section 3(a)(1)(A)(i).
|
||||||
|
|
||||||
|
b. Other rights.
|
||||||
|
|
||||||
|
1. Moral rights, such as the right of integrity, are not
|
||||||
|
licensed under this Public License, nor are publicity,
|
||||||
|
privacy, and/or other similar personality rights; however, to
|
||||||
|
the extent possible, the Licensor waives and/or agrees not to
|
||||||
|
assert any such rights held by the Licensor to the limited
|
||||||
|
extent necessary to allow You to exercise the Licensed
|
||||||
|
Rights, but not otherwise.
|
||||||
|
|
||||||
|
2. Patent and trademark rights are not licensed under this
|
||||||
|
Public License.
|
||||||
|
|
||||||
|
3. To the extent possible, the Licensor waives any right to
|
||||||
|
collect royalties from You for the exercise of the Licensed
|
||||||
|
Rights, whether directly or through a collecting society
|
||||||
|
under any voluntary or waivable statutory or compulsory
|
||||||
|
licensing scheme. In all other cases the Licensor expressly
|
||||||
|
reserves any right to collect such royalties.
|
||||||
|
|
||||||
|
|
||||||
|
Section 3 -- License Conditions.
|
||||||
|
|
||||||
|
Your exercise of the Licensed Rights is expressly made subject to the
|
||||||
|
following conditions.
|
||||||
|
|
||||||
|
a. Attribution.
|
||||||
|
|
||||||
|
1. If You Share the Licensed Material (including in modified
|
||||||
|
form), You must:
|
||||||
|
|
||||||
|
a. retain the following if it is supplied by the Licensor
|
||||||
|
with the Licensed Material:
|
||||||
|
|
||||||
|
i. identification of the creator(s) of the Licensed
|
||||||
|
Material and any others designated to receive
|
||||||
|
attribution, in any reasonable manner requested by
|
||||||
|
the Licensor (including by pseudonym if
|
||||||
|
designated);
|
||||||
|
|
||||||
|
ii. a copyright notice;
|
||||||
|
|
||||||
|
iii. a notice that refers to this Public License;
|
||||||
|
|
||||||
|
iv. a notice that refers to the disclaimer of
|
||||||
|
warranties;
|
||||||
|
|
||||||
|
v. a URI or hyperlink to the Licensed Material to the
|
||||||
|
extent reasonably practicable;
|
||||||
|
|
||||||
|
b. indicate if You modified the Licensed Material and
|
||||||
|
retain an indication of any previous modifications; and
|
||||||
|
|
||||||
|
c. indicate the Licensed Material is licensed under this
|
||||||
|
Public License, and include the text of, or the URI or
|
||||||
|
hyperlink to, this Public License.
|
||||||
|
|
||||||
|
2. You may satisfy the conditions in Section 3(a)(1) in any
|
||||||
|
reasonable manner based on the medium, means, and context in
|
||||||
|
which You Share the Licensed Material. For example, it may be
|
||||||
|
reasonable to satisfy the conditions by providing a URI or
|
||||||
|
hyperlink to a resource that includes the required
|
||||||
|
information.
|
||||||
|
|
||||||
|
3. If requested by the Licensor, You must remove any of the
|
||||||
|
information required by Section 3(a)(1)(A) to the extent
|
||||||
|
reasonably practicable.
|
||||||
|
|
||||||
|
b. ShareAlike.
|
||||||
|
|
||||||
|
In addition to the conditions in Section 3(a), if You Share
|
||||||
|
Adapted Material You produce, the following conditions also apply.
|
||||||
|
|
||||||
|
1. The Adapter's License You apply must be a Creative Commons
|
||||||
|
license with the same License Elements, this version or
|
||||||
|
later, or a BY-SA Compatible License.
|
||||||
|
|
||||||
|
2. You must include the text of, or the URI or hyperlink to, the
|
||||||
|
Adapter's License You apply. You may satisfy this condition
|
||||||
|
in any reasonable manner based on the medium, means, and
|
||||||
|
context in which You Share Adapted Material.
|
||||||
|
|
||||||
|
3. You may not offer or impose any additional or different terms
|
||||||
|
or conditions on, or apply any Effective Technological
|
||||||
|
Measures to, Adapted Material that restrict exercise of the
|
||||||
|
rights granted under the Adapter's License You apply.
|
||||||
|
|
||||||
|
|
||||||
|
Section 4 -- Sui Generis Database Rights.
|
||||||
|
|
||||||
|
Where the Licensed Rights include Sui Generis Database Rights that
|
||||||
|
apply to Your use of the Licensed Material:
|
||||||
|
|
||||||
|
a. for the avoidance of doubt, Section 2(a)(1) grants You the right
|
||||||
|
to extract, reuse, reproduce, and Share all or a substantial
|
||||||
|
portion of the contents of the database;
|
||||||
|
|
||||||
|
b. if You include all or a substantial portion of the database
|
||||||
|
contents in a database in which You have Sui Generis Database
|
||||||
|
Rights, then the database in which You have Sui Generis Database
|
||||||
|
Rights (but not its individual contents) is Adapted Material,
|
||||||
|
including for purposes of Section 3(b); and
|
||||||
|
|
||||||
|
c. You must comply with the conditions in Section 3(a) if You Share
|
||||||
|
all or a substantial portion of the contents of the database.
|
||||||
|
|
||||||
|
For the avoidance of doubt, this Section 4 supplements and does not
|
||||||
|
replace Your obligations under this Public License where the Licensed
|
||||||
|
Rights include other Copyright and Similar Rights.
|
||||||
|
|
||||||
|
|
||||||
|
Section 5 -- Disclaimer of Warranties and Limitation of Liability.
|
||||||
|
|
||||||
|
a. UNLESS OTHERWISE SEPARATELY UNDERTAKEN BY THE LICENSOR, TO THE
|
||||||
|
EXTENT POSSIBLE, THE LICENSOR OFFERS THE LICENSED MATERIAL AS-IS
|
||||||
|
AND AS-AVAILABLE, AND MAKES NO REPRESENTATIONS OR WARRANTIES OF
|
||||||
|
ANY KIND CONCERNING THE LICENSED MATERIAL, WHETHER EXPRESS,
|
||||||
|
IMPLIED, STATUTORY, OR OTHER. THIS INCLUDES, WITHOUT LIMITATION,
|
||||||
|
WARRANTIES OF TITLE, MERCHANTABILITY, FITNESS FOR A PARTICULAR
|
||||||
|
PURPOSE, NON-INFRINGEMENT, ABSENCE OF LATENT OR OTHER DEFECTS,
|
||||||
|
ACCURACY, OR THE PRESENCE OR ABSENCE OF ERRORS, WHETHER OR NOT
|
||||||
|
KNOWN OR DISCOVERABLE. WHERE DISCLAIMERS OF WARRANTIES ARE NOT
|
||||||
|
ALLOWED IN FULL OR IN PART, THIS DISCLAIMER MAY NOT APPLY TO YOU.
|
||||||
|
|
||||||
|
b. TO THE EXTENT POSSIBLE, IN NO EVENT WILL THE LICENSOR BE LIABLE
|
||||||
|
TO YOU ON ANY LEGAL THEORY (INCLUDING, WITHOUT LIMITATION,
|
||||||
|
NEGLIGENCE) OR OTHERWISE FOR ANY DIRECT, SPECIAL, INDIRECT,
|
||||||
|
INCIDENTAL, CONSEQUENTIAL, PUNITIVE, EXEMPLARY, OR OTHER LOSSES,
|
||||||
|
COSTS, EXPENSES, OR DAMAGES ARISING OUT OF THIS PUBLIC LICENSE OR
|
||||||
|
USE OF THE LICENSED MATERIAL, EVEN IF THE LICENSOR HAS BEEN
|
||||||
|
ADVISED OF THE POSSIBILITY OF SUCH LOSSES, COSTS, EXPENSES, OR
|
||||||
|
DAMAGES. WHERE A LIMITATION OF LIABILITY IS NOT ALLOWED IN FULL OR
|
||||||
|
IN PART, THIS LIMITATION MAY NOT APPLY TO YOU.
|
||||||
|
|
||||||
|
c. The disclaimer of warranties and limitation of liability provided
|
||||||
|
above shall be interpreted in a manner that, to the extent
|
||||||
|
possible, most closely approximates an absolute disclaimer and
|
||||||
|
waiver of all liability.
|
||||||
|
|
||||||
|
|
||||||
|
Section 6 -- Term and Termination.
|
||||||
|
|
||||||
|
a. This Public License applies for the term of the Copyright and
|
||||||
|
Similar Rights licensed here. However, if You fail to comply with
|
||||||
|
this Public License, then Your rights under this Public License
|
||||||
|
terminate automatically.
|
||||||
|
|
||||||
|
b. Where Your right to use the Licensed Material has terminated under
|
||||||
|
Section 6(a), it reinstates:
|
||||||
|
|
||||||
|
1. automatically as of the date the violation is cured, provided
|
||||||
|
it is cured within 30 days of Your discovery of the
|
||||||
|
violation; or
|
||||||
|
|
||||||
|
2. upon express reinstatement by the Licensor.
|
||||||
|
|
||||||
|
For the avoidance of doubt, this Section 6(b) does not affect any
|
||||||
|
right the Licensor may have to seek remedies for Your violations
|
||||||
|
of this Public License.
|
||||||
|
|
||||||
|
c. For the avoidance of doubt, the Licensor may also offer the
|
||||||
|
Licensed Material under separate terms or conditions or stop
|
||||||
|
distributing the Licensed Material at any time; however, doing so
|
||||||
|
will not terminate this Public License.
|
||||||
|
|
||||||
|
d. Sections 1, 5, 6, 7, and 8 survive termination of this Public
|
||||||
|
License.
|
||||||
|
|
||||||
|
|
||||||
|
Section 7 -- Other Terms and Conditions.
|
||||||
|
|
||||||
|
a. The Licensor shall not be bound by any additional or different
|
||||||
|
terms or conditions communicated by You unless expressly agreed.
|
||||||
|
|
||||||
|
b. Any arrangements, understandings, or agreements regarding the
|
||||||
|
Licensed Material not stated herein are separate from and
|
||||||
|
independent of the terms and conditions of this Public License.
|
||||||
|
|
||||||
|
|
||||||
|
Section 8 -- Interpretation.
|
||||||
|
|
||||||
|
a. For the avoidance of doubt, this Public License does not, and
|
||||||
|
shall not be interpreted to, reduce, limit, restrict, or impose
|
||||||
|
conditions on any use of the Licensed Material that could lawfully
|
||||||
|
be made without permission under this Public License.
|
||||||
|
|
||||||
|
b. To the extent possible, if any provision of this Public License is
|
||||||
|
deemed unenforceable, it shall be automatically reformed to the
|
||||||
|
minimum extent necessary to make it enforceable. If the provision
|
||||||
|
cannot be reformed, it shall be severed from this Public License
|
||||||
|
without affecting the enforceability of the remaining terms and
|
||||||
|
conditions.
|
||||||
|
|
||||||
|
c. No term or condition of this Public License will be waived and no
|
||||||
|
failure to comply consented to unless expressly agreed to by the
|
||||||
|
Licensor.
|
||||||
|
|
||||||
|
d. Nothing in this Public License constitutes or may be interpreted
|
||||||
|
as a limitation upon, or waiver of, any privileges and immunities
|
||||||
|
that apply to the Licensor or You, including from the legal
|
||||||
|
processes of any jurisdiction or authority.
|
||||||
|
|
||||||
|
|
||||||
|
=======================================================================
|
||||||
|
|
||||||
|
Creative Commons is not a party to its public
|
||||||
|
licenses. Notwithstanding, Creative Commons may elect to apply one of
|
||||||
|
its public licenses to material it publishes and in those instances
|
||||||
|
will be considered the “Licensor.” The text of the Creative Commons
|
||||||
|
public licenses is dedicated to the public domain under the CC0 Public
|
||||||
|
Domain Dedication. Except for the limited purpose of indicating that
|
||||||
|
material is shared under a Creative Commons public license or as
|
||||||
|
otherwise permitted by the Creative Commons policies published at
|
||||||
|
creativecommons.org/policies, Creative Commons does not authorize the
|
||||||
|
use of the trademark "Creative Commons" or any other trademark or logo
|
||||||
|
of Creative Commons without its prior written consent including,
|
||||||
|
without limitation, in connection with any unauthorized modifications
|
||||||
|
to any of its public licenses or any other arrangements,
|
||||||
|
understandings, or agreements concerning use of licensed material. For
|
||||||
|
the avoidance of doubt, this paragraph does not form part of the
|
||||||
|
public licenses.
|
||||||
|
|
||||||
|
Creative Commons may be contacted at creativecommons.org.
|
@@ -7,6 +7,8 @@ This case provides a convenient way to cover up the SuperSensor's PCB, either
|
|||||||
for aesthetics or to help protect it from harsh environments.
|
for aesthetics or to help protect it from harsh environments.
|
||||||
|
|
||||||
You can [tinker the design on TinkerCAD here](https://www.tinkercad.com/things/1HT3fyNbln0-supersensor-case).
|
You can [tinker the design on TinkerCAD here](https://www.tinkercad.com/things/1HT3fyNbln0-supersensor-case).
|
||||||
|
The case design and images in this folder are licensed under the Creative Commons
|
||||||
|
Attribution-ShareAlike (BY-SA) 4.0 license.
|
||||||
|
|
||||||
## Printing
|
## Printing
|
||||||
|
|
||||||
@@ -71,7 +73,7 @@ To begin, print the parts above as indicated; default slicer settings should be
|
|||||||
We will exclude the USB cable opening extension for this assembly, but its installation
|
We will exclude the USB cable opening extension for this assembly, but its installation
|
||||||
is straightforward.
|
is straightforward.
|
||||||
|
|
||||||
1. Lay out the parts; you will need:
|
Lay out the parts; you will need:
|
||||||
|
|
||||||
* The body, face, insert, and AM312 tube parts.
|
* The body, face, insert, and AM312 tube parts.
|
||||||
* Superglue
|
* Superglue
|
||||||
@@ -80,51 +82,55 @@ is straightforward.
|
|||||||
|
|
||||||

|

|
||||||
|
|
||||||
2. Place the face face-down (clips up), and place dabs of superglue at the corners of the
|
### Face
|
||||||
|
|
||||||
|
1. Place the face face-down (clips up), and place dabs of superglue at the corners of the
|
||||||
insert openings.
|
insert openings.
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
3. Spread the superglue along the inner edges with the toothpick; or, combine 2+3 by using
|
2. Spread the superglue along the inner edges with the toothpick; or, combine 2+3 by using
|
||||||
a precision superglue applicator. You need very little glue here; avoid extra ooze!
|
a precision superglue applicator. You need very little glue here; avoid extra ooze!
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
4. Firmly place the insert face-down into the hole; the overlap edges should match.
|
3. Firmly place the insert face-down into the hole; the overlap edges should match.
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
5. Apply firm pressure to both sides of the insert with your thumbs, a vice, or another
|
4. Apply firm pressure to both sides of the insert with your thumbs, a vice, or another
|
||||||
pressing object, until the glue can set up (15-30 seconds).
|
pressing object, until the glue can set up (15-30 seconds).
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
6. Flip over the face; the insert should now be solidly affixed. Clean up any oozing superglue
|
5. Flip over the face; the insert should now be solidly affixed. Clean up any oozing superglue
|
||||||
with a paper towel or lint-free rag.
|
with a paper towel or lint-free rag.
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
7. Place a small amount of superglue on your toothpick tip; if using a precision superglue
|
6. Place a small amount of superglue on your toothpick tip; if using a precision superglue
|
||||||
applicator, skip this step.
|
applicator, skip this step.
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
8. Gently spread the superglue around the circular opening (or apply using a precision superglue
|
7. Gently spread the superglue around the circular opening (or apply using a precision superglue
|
||||||
applicator); you want the bead to be no more than 1mm wide to avoid ooze.
|
applicator); you want the bead to be no more than 1mm wide to avoid ooze.
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
9. Line up the AM312 tube, and firmly press it down to seal. Clean up any oozing superglue
|
8. Line up the AM312 tube, and firmly press it down to seal. Clean up any oozing superglue
|
||||||
with a paper towel or lint-free rag.
|
with a paper towel or lint-free rag.
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
You will now have a completed face assembly and are ready to install the actual SuperSensor.
|
You will now have a completed face assembly and are ready to install the actual SuperSensor.
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
10. Gently insert the SuperSensor board into the case body, lining it up with the four standoffs.
|
### Body
|
||||||
Gently press down until the ESP32 is firmly sitting on the bottom (it should require no force).
|
|
||||||
|
1. Gently insert the SuperSensor board into the case body, lining it up with the four standoffs.
|
||||||
|
The ESP32 should b firmly sitting on the bottom (it should require no force).
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
@@ -132,29 +138,29 @@ is straightforward.
|
|||||||
|
|
||||||

|

|
||||||
|
|
||||||
11. Remove the top cap of the AM312.
|
2. Remove the top cap of the AM312.
|
||||||
|
|
||||||
12. Place the face over the AM312.
|
3. Place the face over the AM312.
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
13. Line up the clips on one side (I prefer the left). Then using a gentle squeezing motion, apply
|
4. Line up the clips on one side (I prefer the left). Then using a gentle squeezing motion, apply
|
||||||
pressur eto the sides of the case on the right side while also applying lateral pressure on
|
pressure to the sides of the case on the right side while also applying lateral pressure on
|
||||||
the face towards the inserted clips. This picture is a one-handed demonstration, applying a
|
the face towards the inserted clips. This picture is a one-handed demonstration, applying a
|
||||||
squeezing pressure between my thumb and middle finger and a downwards pressure with my index
|
squeezing pressure between my thumb and middle finger and a downwards pressure with my index
|
||||||
finger to provide force; using two hands is advised.
|
finger to provide force; using two hands is advised.
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
14. While doing the previous step, ensure that the 3 sensor holes are lined up with their corresponding sensors.
|
5. While doing the previous step, ensure that the 3 sensor holes are lined up with their corresponding sensors.
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
15. Press the face into the body so that all 4 clips are making contact.
|
6. Press the face into the body so that all 4 clips are making contact.
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
16. Reinstall the top cap of the AM312; it should have a snug fit against the tube.
|
7. Reinstall the top cap of the AM312; it should have a snug fit against the tube.
|
||||||
|
|
||||||
You now have an assembled case!
|
You now have an assembled case!
|
||||||
|
|
||||||
@@ -162,3 +168,10 @@ You now have an assembled case!
|
|||||||
|
|
||||||
As a further step, consider placing a line of tape around the face-body joint. The locking clip
|
As a further step, consider placing a line of tape around the face-body joint. The locking clip
|
||||||
design was made with printing in mind, and does have some play here.
|
design was made with printing in mind, and does have some play here.
|
||||||
|
|
||||||
|
## Installation
|
||||||
|
|
||||||
|
You may either mount the SuperSensor by its USB plug (as with a bare board design), or by attaching
|
||||||
|
a mounting piece to the case. Enjoy your newly-enclosed SuperSensor with diffused status LEDs!
|
||||||
|
|
||||||
|

|
||||||
|
349
supersensor.yaml
349
supersensor.yaml
@@ -89,6 +89,51 @@ globals:
|
|||||||
restore_value: true
|
restore_value: true
|
||||||
initial_value: "0.0"
|
initial_value: "0.0"
|
||||||
|
|
||||||
|
- id: room_health_temperature_min
|
||||||
|
type: float
|
||||||
|
restore_value: true
|
||||||
|
initial_value: "21.0"
|
||||||
|
|
||||||
|
- id: room_health_temperature_max
|
||||||
|
type: float
|
||||||
|
restore_value: true
|
||||||
|
initial_value: "24.0"
|
||||||
|
|
||||||
|
- id: room_health_temperature_penalty
|
||||||
|
type: float
|
||||||
|
restore_value: true
|
||||||
|
initial_value: "10.0"
|
||||||
|
|
||||||
|
- id: room_health_humidity_min
|
||||||
|
type: float
|
||||||
|
restore_value: true
|
||||||
|
initial_value: "40.0"
|
||||||
|
|
||||||
|
- id: room_health_humidity_max
|
||||||
|
type: float
|
||||||
|
restore_value: true
|
||||||
|
initial_value: "60.0"
|
||||||
|
|
||||||
|
- id: room_health_humidity_penalty
|
||||||
|
type: float
|
||||||
|
restore_value: true
|
||||||
|
initial_value: "5.0"
|
||||||
|
|
||||||
|
- id: room_health_voc_weight
|
||||||
|
type: float
|
||||||
|
restore_value: true
|
||||||
|
initial_value: "0.4"
|
||||||
|
|
||||||
|
- id: room_health_temperature_weight
|
||||||
|
type: float
|
||||||
|
restore_value: true
|
||||||
|
initial_value: "0.3"
|
||||||
|
|
||||||
|
- id: room_health_humidity_weight
|
||||||
|
type: float
|
||||||
|
restore_value: true
|
||||||
|
initial_value: "0.3"
|
||||||
|
|
||||||
- id: pir_hold_time
|
- id: pir_hold_time
|
||||||
type: int
|
type: int
|
||||||
restore_value: true
|
restore_value: true
|
||||||
@@ -120,6 +165,20 @@ globals:
|
|||||||
initial_value: '"mww_computer"'
|
initial_value: '"mww_computer"'
|
||||||
|
|
||||||
script:
|
script:
|
||||||
|
- id: presence_light_on
|
||||||
|
then:
|
||||||
|
if:
|
||||||
|
condition:
|
||||||
|
- switch.is_on: enable_presence_led
|
||||||
|
- light.is_off: output_led
|
||||||
|
then:
|
||||||
|
- light.turn_on:
|
||||||
|
id: output_led
|
||||||
|
brightness: 25%
|
||||||
|
red: 1
|
||||||
|
green: 1
|
||||||
|
blue: 1
|
||||||
|
transition_length: 1s
|
||||||
- id: light_off
|
- id: light_off
|
||||||
then:
|
then:
|
||||||
if:
|
if:
|
||||||
@@ -354,13 +413,13 @@ i2s_audio:
|
|||||||
number: GPIO17 # WS
|
number: GPIO17 # WS
|
||||||
i2s_bclk_pin:
|
i2s_bclk_pin:
|
||||||
number: GPIO16 # SCK
|
number: GPIO16 # SCK
|
||||||
# Dummy I2S audio pipeline for "speaker"
|
# # Dummy I2S audio pipeline for "speaker"
|
||||||
- id: i2s_dummy
|
# - id: i2s_dummy
|
||||||
i2s_lrclk_pin:
|
# i2s_lrclk_pin:
|
||||||
number: GPIO15 # WS
|
# number: GPIO15 # WS
|
||||||
ignore_strapping_warning: true # This isn't connected to anything anyways
|
# ignore_strapping_warning: true # This isn't connected to anything anyways
|
||||||
i2s_bclk_pin:
|
# i2s_bclk_pin:
|
||||||
number: GPIO14 # SCK
|
# number: GPIO14 # SCK
|
||||||
|
|
||||||
microphone:
|
microphone:
|
||||||
- platform: i2s_audio
|
- platform: i2s_audio
|
||||||
@@ -371,17 +430,17 @@ microphone:
|
|||||||
pdm: false
|
pdm: false
|
||||||
channel: left
|
channel: left
|
||||||
|
|
||||||
speaker:
|
#speaker:
|
||||||
# Dummy speaker to fix home-assistant/core#142363
|
# # Dummy speaker to fix home-assistant/core#142363
|
||||||
- platform: i2s_audio
|
# - platform: i2s_audio
|
||||||
id: dummy_speaker
|
# id: dummy_speaker
|
||||||
i2s_audio_id: i2s_dummy
|
# i2s_audio_id: i2s_dummy
|
||||||
i2s_dout_pin: GPIO25
|
# i2s_dout_pin: GPIO25
|
||||||
dac_type: external
|
# dac_type: external
|
||||||
bits_per_sample: 16bit
|
# bits_per_sample: 16bit
|
||||||
sample_rate: 16000
|
# sample_rate: 16000
|
||||||
channel: mono #mono will have bad performance, however, we are not using the on device speaker
|
# channel: mono #mono will have bad performance, however, we are not using the on device speaker
|
||||||
buffer_duration: 60ms
|
# buffer_duration: 60ms
|
||||||
|
|
||||||
micro_wake_word:
|
micro_wake_word:
|
||||||
id: mww
|
id: mww
|
||||||
@@ -414,7 +473,7 @@ micro_wake_word:
|
|||||||
voice_assistant:
|
voice_assistant:
|
||||||
id: va
|
id: va
|
||||||
microphone: mic
|
microphone: mic
|
||||||
speaker: dummy_speaker
|
# speaker: dummy_speaker
|
||||||
micro_wake_word: mww
|
micro_wake_word: mww
|
||||||
use_wake_word: false
|
use_wake_word: false
|
||||||
noise_suppression_level: 3
|
noise_suppression_level: 3
|
||||||
@@ -459,6 +518,7 @@ voice_assistant:
|
|||||||
red: 1
|
red: 1
|
||||||
green: 0
|
green: 0
|
||||||
blue: 0
|
blue: 0
|
||||||
|
- voice_assistant.stop:
|
||||||
else:
|
else:
|
||||||
- logger.log: "Command successful!"
|
- logger.log: "Command successful!"
|
||||||
- light.turn_on:
|
- light.turn_on:
|
||||||
@@ -468,6 +528,10 @@ voice_assistant:
|
|||||||
red: 0
|
red: 0
|
||||||
green: 1
|
green: 1
|
||||||
blue: 0
|
blue: 0
|
||||||
|
- voice_assistant.stop:
|
||||||
|
on_tts_end:
|
||||||
|
- logger.log: "Finished STT result"
|
||||||
|
- voice_assistant.stop:
|
||||||
|
|
||||||
light:
|
light:
|
||||||
- platform: rgb
|
- platform: rgb
|
||||||
@@ -543,13 +607,13 @@ sensor:
|
|||||||
|
|
||||||
- platform: debug
|
- platform: debug
|
||||||
free:
|
free:
|
||||||
name: "Heap Free"
|
name: "ESP32 Heap Free"
|
||||||
block:
|
block:
|
||||||
name: "Heap Max Block"
|
name: "ESP32 Heap Max Block"
|
||||||
loop_time:
|
loop_time:
|
||||||
name: "Loop Time"
|
name: "ESP32 Loop Time"
|
||||||
cpu_frequency:
|
cpu_frequency:
|
||||||
name: "CPU Frequency"
|
name: "ESP32 CPU Frequency"
|
||||||
|
|
||||||
- platform: sgp4x
|
- platform: sgp4x
|
||||||
voc:
|
voc:
|
||||||
@@ -662,30 +726,61 @@ sensor:
|
|||||||
unit_of_measurement: "%"
|
unit_of_measurement: "%"
|
||||||
icon: mdi:home-heart
|
icon: mdi:home-heart
|
||||||
lambda: |-
|
lambda: |-
|
||||||
float voc_index = id(sgp41_voc_index).state;
|
float voc = id(sgp41_tvoc_ppb).state;
|
||||||
|
if (isnan(voc) || voc < 1) voc = 1;
|
||||||
float temp = id(sht45_temperature).state;
|
float temp = id(sht45_temperature).state;
|
||||||
float humidity = id(sht45_humidity).state;
|
float humidity = id(sht45_humidity).state;
|
||||||
|
|
||||||
// VOC Score (0–100)
|
float temp_min = id(room_health_temperature_min);
|
||||||
float voc_score = 0;
|
float temp_max = id(room_health_temperature_max);
|
||||||
if (voc_index <= 100) voc_score = 100;
|
float temp_penalty = id(room_health_temperature_penalty);
|
||||||
else if (voc_index <= 200) voc_score = 80;
|
float humid_min = id(room_health_humidity_min);
|
||||||
else if (voc_index <= 300) voc_score = 60;
|
float humid_max = id(room_health_humidity_max);
|
||||||
else if (voc_index <= 400) voc_score = 40;
|
float humid_penalty = id(room_health_humidity_penalty);
|
||||||
else if (voc_index <= 500) voc_score = 50;
|
float voc_weight = id(room_health_voc_weight);
|
||||||
else voc_score = 0;
|
float temp_weight = id(room_health_temperature_weight);
|
||||||
|
float humid_weight = id(room_health_humidity_weight);
|
||||||
// Temperature Score (0–100)
|
|
||||||
float temp_score = 100.0 - abs(temp - 23.0) * 10.0;
|
// VOC score (0–100) mapped to categories from Chemical Pollution levels below
|
||||||
|
float voc_score;
|
||||||
|
if (voc <= 200) {
|
||||||
|
voc_score = 100.0;
|
||||||
|
} else if (voc <= 400) {
|
||||||
|
// 200–400: 100 → 90
|
||||||
|
voc_score = 100.0 - (voc - 200) * (10.0 / 200.0);
|
||||||
|
} else if (voc <= 600) {
|
||||||
|
// 400–600: 90 → 70
|
||||||
|
voc_score = 90.0 - (voc - 400) * (20.0 / 200.0);
|
||||||
|
} else if (voc <= 1500) {
|
||||||
|
// 600–1500: 70 → 40
|
||||||
|
voc_score = 70.0 - (voc - 600) * (30.0 / 900.0);
|
||||||
|
} else if (voc <= 3000) {
|
||||||
|
// 1500–3000: 40 → 0
|
||||||
|
voc_score = 40.0 - (voc - 1500) * (40.0 / 1500.0);
|
||||||
|
} else {
|
||||||
|
voc_score = 0.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Temperature score
|
||||||
|
float temp_score = 100;
|
||||||
|
if (temp < temp_min) temp_score = 100 - (temp_min - temp) * temp_penalty;
|
||||||
|
else if (temp > temp_max) temp_score = 100 - (temp - temp_max) * temp_penalty;
|
||||||
if (temp_score < 0) temp_score = 0;
|
if (temp_score < 0) temp_score = 0;
|
||||||
|
|
||||||
// Humidity Score (0–100), ideal range 35–55%
|
// Humidity score
|
||||||
float humidity_score = 100.0 - abs(humidity - 50.0) * 3.0;
|
float humidity_score = 100;
|
||||||
|
if (humidity < humid_min) humidity_score = 100 - (humid_min - humidity) * humid_penalty;
|
||||||
|
else if (humidity > humid_max) humidity_score = 100 - (humidity - humid_max) * humid_penalty;
|
||||||
if (humidity_score < 0) humidity_score = 0;
|
if (humidity_score < 0) humidity_score = 0;
|
||||||
|
|
||||||
// Weighted average
|
// Weighted average
|
||||||
float overall_score = (voc_score * 0.5 + temp_score * 0.25 + humidity_score * 0.25);
|
float total_weights = voc_weight + temp_weight + humid_weight;
|
||||||
|
if (total_weights <= 0) total_weights = 1.0;
|
||||||
|
voc_weight /= total_weights;
|
||||||
|
temp_weight /= total_weights;
|
||||||
|
humid_weight /= total_weights;
|
||||||
|
float overall_score = (voc_score * voc_weight + temp_score * temp_weight + humidity_score * humid_weight);
|
||||||
|
|
||||||
return (int) round(overall_score);
|
return (int) round(overall_score);
|
||||||
update_interval: 15s
|
update_interval: 15s
|
||||||
|
|
||||||
@@ -741,7 +836,7 @@ binary_sensor:
|
|||||||
device_class: occupancy
|
device_class: occupancy
|
||||||
on_state:
|
on_state:
|
||||||
then:
|
then:
|
||||||
- script.execute: light_off
|
- script.execute: presence_light_on
|
||||||
|
|
||||||
- platform: gpio
|
- platform: gpio
|
||||||
name: "PIR GPIO"
|
name: "PIR GPIO"
|
||||||
@@ -823,12 +918,12 @@ text_sensor:
|
|||||||
id: sgp41_chemical_pollution
|
id: sgp41_chemical_pollution
|
||||||
icon: mdi:molecule
|
icon: mdi:molecule
|
||||||
lambda: |-
|
lambda: |-
|
||||||
float voc_index = id(sgp41_voc_index).state;
|
float voc = id(sgp41_tvoc_ppb).state;
|
||||||
if (voc_index < 1 || voc_index > 500) return {"Unknown"};
|
if (isnan(voc) || voc < 1) return {"Unknown"};
|
||||||
if (voc_index <= 100) return {"Excellent"};
|
else if (voc <= 200) return {"Excellent"};
|
||||||
else if (voc_index <= 200) return {"Good"};
|
else if (voc <= 400) return {"Good"};
|
||||||
else if (voc_index <= 300) return {"Moderate"};
|
else if (voc <= 600) return {"Moderate"};
|
||||||
else if (voc_index <= 400) return {"Unhealthy"};
|
else if (voc <= 1500) return {"Unhealthy"};
|
||||||
else return {"Hazardous"};
|
else return {"Hazardous"};
|
||||||
update_interval: 15s
|
update_interval: 15s
|
||||||
|
|
||||||
@@ -839,10 +934,10 @@ text_sensor:
|
|||||||
lambda: |-
|
lambda: |-
|
||||||
float score = id(room_health_score).state;
|
float score = id(room_health_score).state;
|
||||||
if (score < 0) return {"Unknown"};
|
if (score < 0) return {"Unknown"};
|
||||||
else if (score >= 90.0) return {"Great"};
|
else if (score >= 95.0) return {"Great"};
|
||||||
else if (score >= 80.0) return {"Good"};
|
else if (score >= 90.0) return {"Good"};
|
||||||
else if (score >= 60.0) return {"Fair"};
|
else if (score >= 80.0) return {"Fair"};
|
||||||
else if (score >= 40.0) return {"Poor"};
|
else if (score >= 60.0) return {"Poor"};
|
||||||
else return {"Bad"};
|
else return {"Bad"};
|
||||||
update_interval: 15s
|
update_interval: 15s
|
||||||
|
|
||||||
@@ -965,6 +1060,154 @@ number:
|
|||||||
id: light_presence_threshold
|
id: light_presence_threshold
|
||||||
value: !lambda 'return int(x);'
|
value: !lambda 'return int(x);'
|
||||||
|
|
||||||
|
# Room Health Calibration Values
|
||||||
|
# These values allow the user to tweak the values of the room health calculation
|
||||||
|
- platform: template
|
||||||
|
name: "Room Health Min Temperature"
|
||||||
|
id: room_health_temperature_min_setter
|
||||||
|
min_value: 15
|
||||||
|
max_value: 30
|
||||||
|
step: 0.5
|
||||||
|
lambda: |-
|
||||||
|
return id(room_health_temperature_min);
|
||||||
|
set_action:
|
||||||
|
then:
|
||||||
|
- globals.set:
|
||||||
|
id: room_health_temperature_min
|
||||||
|
value: !lambda 'return float(x);'
|
||||||
|
- platform: template
|
||||||
|
name: "Room Health Max Temperature"
|
||||||
|
id: room_health_temperature_max_setter
|
||||||
|
min_value: 15
|
||||||
|
max_value: 30
|
||||||
|
step: 0.5
|
||||||
|
lambda: |-
|
||||||
|
return id(room_health_temperature_max);
|
||||||
|
set_action:
|
||||||
|
then:
|
||||||
|
- globals.set:
|
||||||
|
id: room_health_temperature_max
|
||||||
|
value: !lambda 'return float(x);'
|
||||||
|
- platform: template
|
||||||
|
name: "Room Health Temperature Penalty"
|
||||||
|
id: room_health_temperature_penalty_setter
|
||||||
|
min_value: 1
|
||||||
|
max_value: 20
|
||||||
|
step: 1
|
||||||
|
lambda: |-
|
||||||
|
return int(id(room_health_temperature_penalty));
|
||||||
|
set_action:
|
||||||
|
then:
|
||||||
|
- globals.set:
|
||||||
|
id: room_health_temperature_penalty
|
||||||
|
value: !lambda 'return float(x);'
|
||||||
|
- platform: template
|
||||||
|
name: "Room Health Min Humidity"
|
||||||
|
id: room_health_humidity_min_setter
|
||||||
|
min_value: 20
|
||||||
|
max_value: 80
|
||||||
|
step: 1.0
|
||||||
|
lambda: |-
|
||||||
|
return id(room_health_humidity_min);
|
||||||
|
set_action:
|
||||||
|
then:
|
||||||
|
- globals.set:
|
||||||
|
id: room_health_humidity_min
|
||||||
|
value: !lambda 'return float(x);'
|
||||||
|
- platform: template
|
||||||
|
name: "Room Health Max Humidity"
|
||||||
|
id: room_health_humidity_max_setter
|
||||||
|
min_value: 20
|
||||||
|
max_value: 80
|
||||||
|
step: 1.0
|
||||||
|
lambda: |-
|
||||||
|
return id(room_health_humidity_max);
|
||||||
|
set_action:
|
||||||
|
then:
|
||||||
|
- globals.set:
|
||||||
|
id: room_health_humidity_max
|
||||||
|
value: !lambda 'return float(x);'
|
||||||
|
- platform: template
|
||||||
|
name: "Room Health Humidity Penalty"
|
||||||
|
id: room_health_humidity_penalty_setter
|
||||||
|
min_value: 1
|
||||||
|
max_value: 10
|
||||||
|
step: 1
|
||||||
|
lambda: |-
|
||||||
|
return int(id(room_health_humidity_penalty));
|
||||||
|
set_action:
|
||||||
|
then:
|
||||||
|
- globals.set:
|
||||||
|
id: room_health_humidity_penalty
|
||||||
|
value: !lambda 'return float(x);'
|
||||||
|
- platform: template
|
||||||
|
name: "Room Health VOC Weight"
|
||||||
|
id: room_health_voc_weight_setter
|
||||||
|
min_value: 0.00
|
||||||
|
max_value: 1.00
|
||||||
|
step: 0.01
|
||||||
|
lambda: |-
|
||||||
|
return id(room_health_voc_weight);
|
||||||
|
set_action:
|
||||||
|
- if:
|
||||||
|
condition:
|
||||||
|
lambda: |-
|
||||||
|
float total = x + id(room_health_temperature_weight) + id(room_health_humidity_weight);
|
||||||
|
return (total > 0.0) && (total <= 1.0);
|
||||||
|
then:
|
||||||
|
- globals.set:
|
||||||
|
id: room_health_voc_weight
|
||||||
|
value: !lambda 'return float(x);'
|
||||||
|
else:
|
||||||
|
- logger.log:
|
||||||
|
format: "Rejected VOC weight %.2f (total would be out of range: must be > 0.0 and ≤ 1.0)"
|
||||||
|
args: [ 'x' ]
|
||||||
|
- platform: template
|
||||||
|
name: "Room Health Temperature Weight"
|
||||||
|
id: room_health_temperature_weight_setter
|
||||||
|
min_value: 0.00
|
||||||
|
max_value: 1.00
|
||||||
|
step: 0.01
|
||||||
|
lambda: |-
|
||||||
|
return id(room_health_temperature_weight);
|
||||||
|
set_action:
|
||||||
|
- if:
|
||||||
|
condition:
|
||||||
|
lambda: |-
|
||||||
|
float total = x + id(room_health_voc_weight) + id(room_health_humidity_weight);
|
||||||
|
return (total > 0.0) && (total <= 1.0);
|
||||||
|
then:
|
||||||
|
- globals.set:
|
||||||
|
id: room_health_temperature_weight
|
||||||
|
value: !lambda 'return float(x);'
|
||||||
|
else:
|
||||||
|
- logger.log:
|
||||||
|
format: "Rejected Temperature weight %.2f (total would be out of range: must be > 0.0 and ≤ 1.0)"
|
||||||
|
args: [ 'x' ]
|
||||||
|
- platform: template
|
||||||
|
name: "Room Health Humidity Weight"
|
||||||
|
id: room_health_humidity_weight_setter
|
||||||
|
min_value: 0.00
|
||||||
|
max_value: 1.00
|
||||||
|
step: 0.01
|
||||||
|
lambda: |-
|
||||||
|
return id(room_health_humidity_weight);
|
||||||
|
set_action:
|
||||||
|
- if:
|
||||||
|
condition:
|
||||||
|
lambda: |-
|
||||||
|
float total = x + id(room_health_temperature_weight) + id(room_health_voc_weight);
|
||||||
|
return (total > 0.0) && (total <= 1.0);
|
||||||
|
then:
|
||||||
|
- globals.set:
|
||||||
|
id: room_health_humidity_weight
|
||||||
|
value: !lambda 'return float(x);'
|
||||||
|
else:
|
||||||
|
- logger.log:
|
||||||
|
format: "Rejected Humidity weight %.2f (total would be out of range: must be > 0.0 and ≤ 1.0)"
|
||||||
|
args: [ 'x' ]
|
||||||
|
|
||||||
|
# LD2410c configuration values
|
||||||
- platform: ld2410
|
- platform: ld2410
|
||||||
timeout:
|
timeout:
|
||||||
name: "LD2410C Timeout"
|
name: "LD2410C Timeout"
|
||||||
|
Reference in New Issue
Block a user