1
0
mirror of https://github.com/Utyff/Zintercom.git synced 2026-01-12 09:17:41 +03:00

33 Commits

Author SHA1 Message Date
xyzroe
5b2db2f803 Create FUNDING.yml 2024-03-30 00:26:10 +02:00
xyzroe
07114547b4 Update converter to support z2m v1.35 2024-01-07 15:49:38 +02:00
xyzroe
abc32f88fa Update README.md 2023-09-06 12:20:31 +03:00
xyzroe
eb86a39868 Update README.md 2022-07-05 01:31:01 +03:00
xyzroe
8995c3bd33 Update README.md 2022-05-19 19:51:09 +03:00
xyzroe
c4e44672ad Merge pull request #8 from Utyff/Utyf
Support RGB Led and One Led, some small fixes, add RBG scheme and Gerber files
2022-05-19 19:40:11 +03:00
Utyf
256055d1fb RGB version info 2022-04-27 01:20:56 +03:00
Utyf
afdc4348c4 Open and Drop by button and command 2022-04-25 17:21:27 +03:00
Utyf
2707f5c987 support battery and old LED 2022-03-16 01:11:52 +03:00
Utyf
1fd4c7b2fa fix button press 2022-03-13 05:19:50 +03:00
Utyf
b786d8bfdd remove led timer 2022-03-05 22:53:36 +03:00
Utyf
4fbab14965 RGB and UART works 2022-02-26 00:34:49 +03:00
Utyf
17ee0a7588 modify RGB 2022-02-23 19:20:53 +03:00
Utyf
6fe29470ec set old led 2022-02-20 20:15:06 +03:00
Utyf
07f7ac2147 cleanup 2022-02-20 16:35:16 +03:00
Utyf
b2ac615230 Merge branch 'rgb_led' into master
# Conflicts:
#	Source/preinclude.h
#	Source/zcl_app.c
2022-02-20 12:28:51 +03:00
lost
d5e35b9e49 Small fix :) 2022-02-16 23:37:42 +02:00
lost
921e8c1309 Add binary switches for different modes 2022-02-16 23:13:05 +02:00
lost
23e04d3571 Add RGB led support
Rework button actions (single, double, hold)
Detail description can be found in hardware/Домофон zintercom.docx
2022-02-16 22:09:22 +02:00
xyzroe
e98969e3c5 Merge pull request #6 from Utyff/Utyf
fix button hold
2022-02-12 19:49:08 +02:00
Utyf
a3ec8d06b0 fix button hold 2022-02-12 14:34:48 +03:00
Utyf
66869f7d0c project fix 2022-02-07 12:25:02 +03:00
xyzroe
db6995dc7b Merge pull request #4 from nurikk/patch-1
Update README.md
2021-08-09 16:51:39 +03:00
John Doe
7994aead0c Update README.md 2021-08-07 00:05:37 +08:00
John Doe
5de49cbeae Update README.md 2021-08-06 23:32:08 +08:00
xyzroe
6255791281 Update README.md 2021-07-04 12:22:06 +03:00
xyzroe
a872b42ff1 additional intercom connection info and diagrams 2021-06-24 14:43:37 +03:00
xyzroe
b2d9a718a4 Add files via upload 2021-06-24 14:37:34 +03:00
xyzroe
21106958c5 Add files via upload 2021-06-24 14:36:21 +03:00
lost
e58b8a0f97 added TimeBell attribute than means time after last bell to finish ring 2021-06-15 15:29:00 +03:00
lost
0439847dd5 Merge branch 'master' of github.com:diyruz/Zintercom into master 2021-06-15 13:56:44 +03:00
lost
a34f4319d9 events' timers reworked 2021-06-15 13:56:25 +03:00
xyzroe
c9ff7819b2 Update README.md
Added:
1. Error description about Gerber PCB v1.0 committed on Apr 14
2. Image and link to the 3d model of the case.
2021-06-14 14:12:34 +03:00
16 changed files with 435 additions and 196 deletions

14
.github/FUNDING.yml vendored Normal file
View File

@@ -0,0 +1,14 @@
# These are supported funding model platforms
github: xyzroe
patreon: # Replace with a single Patreon username
open_collective: # Replace with a single Open Collective username
ko_fi: # Replace with a single Ko-fi username
tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
liberapay: # Replace with a single Liberapay username
issuehunt: # Replace with a single IssueHunt username
lfx_crowdfunding: # Replace with a single LFX Crowdfunding project-name e.g., cloud-foundry
polar: # Replace with a single Polar username
buy_me_a_coffee: xyzroe
custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2']

View File

@@ -142,11 +142,11 @@
<option> <option>
<name>Input variant</name> <name>Input variant</name>
<version>2</version> <version>2</version>
<state>0</state> <state>5</state>
</option> </option>
<option> <option>
<name>Input description</name> <name>Input description</name>
<state>Automatic choice of formatter.</state> <state>No float.</state>
</option> </option>
<option> <option>
<name>Output variant</name> <name>Output variant</name>
@@ -1284,11 +1284,11 @@
<option> <option>
<name>Input variant</name> <name>Input variant</name>
<version>2</version> <version>2</version>
<state>0</state> <state>5</state>
</option> </option>
<option> <option>
<name>Input description</name> <name>Input description</name>
<state>Automatic choice of formatter.</state> <state>No float.</state>
</option> </option>
<option> <option>
<name>Output variant</name> <name>Output variant</name>
@@ -1604,7 +1604,7 @@
<option> <option>
<name>Compiler Extra Options Edit</name> <name>Compiler Extra Options Edit</name>
<state>-f $PROJ_DIR$\..\..\..\Tools\CC2530DB\f8wRouter.cfg</state> <state>-f $PROJ_DIR$\..\..\..\Tools\CC2530DB\f8wRouter.cfg</state>
<state>-f $PROJ_DIR$\..\..\..\Tools\CC2530DB\f8wConfig.cfg</state> <state>-f $PROJ_DIR$\..\zstack-lib\f8wConfig.cfg</state>
<state>-f $PROJ_DIR$\..\..\..\Tools\CC2530DB\f8wZCL.cfg</state> <state>-f $PROJ_DIR$\..\..\..\Tools\CC2530DB\f8wZCL.cfg</state>
</option> </option>
<option> <option>
@@ -3704,7 +3704,7 @@
</option> </option>
<option> <option>
<name>OGChipConfigPath</name> <name>OGChipConfigPath</name>
<state>$TOOLKIT_DIR$\config\devices\Texas Instruments\CC2530F256.i51</state> <state>$TOOLKIT_DIR$\config\devices\Texas Instruments\CC25xx\3x\CC2530F256.i51</state>
</option> </option>
</data> </data>
</settings> </settings>
@@ -3887,7 +3887,7 @@
<option> <option>
<name>Compiler Extra Options Edit</name> <name>Compiler Extra Options Edit</name>
<state>-f $PROJ_DIR$\..\..\..\Tools\CC2530DB\f8wRouter.cfg</state> <state>-f $PROJ_DIR$\..\..\..\Tools\CC2530DB\f8wRouter.cfg</state>
<state>-f $PROJ_DIR$\..\..\..\Tools\CC2530DB\f8wConfig.cfg</state> <state>-f $PROJ_DIR$\..\zstack-lib\f8wConfig.cfg</state>
<state>-f $PROJ_DIR$\..\..\..\Tools\CC2530DB\f8wZCL.cfg</state> <state>-f $PROJ_DIR$\..\..\..\Tools\CC2530DB\f8wZCL.cfg</state>
</option> </option>
<option> <option>
@@ -5989,7 +5989,7 @@
</option> </option>
<option> <option>
<name>OGChipConfigPath</name> <name>OGChipConfigPath</name>
<state>$TOOLKIT_DIR$\config\devices\Texas Instruments\CC2530F256.i51</state> <state>$TOOLKIT_DIR$\config\devices\Texas Instruments\CC25xx\3x\CC2530F256.i51</state>
</option> </option>
</data> </data>
</settings> </settings>
@@ -6174,7 +6174,7 @@
<option> <option>
<name>Compiler Extra Options Edit</name> <name>Compiler Extra Options Edit</name>
<state>-f $PROJ_DIR$\..\..\..\Tools\CC2530DB\f8wRouter.cfg</state> <state>-f $PROJ_DIR$\..\..\..\Tools\CC2530DB\f8wRouter.cfg</state>
<state>-f $PROJ_DIR$\..\..\..\Tools\CC2530DB\f8wConfig.cfg</state> <state>-f $PROJ_DIR$\..\zstack-lib\f8wConfig.cfg</state>
<state>-f $PROJ_DIR$\..\..\..\Tools\CC2530DB\f8wZCL.cfg</state> <state>-f $PROJ_DIR$\..\..\..\Tools\CC2530DB\f8wZCL.cfg</state>
</option> </option>
<option> <option>
@@ -8276,7 +8276,7 @@
</option> </option>
<option> <option>
<name>OGChipConfigPath</name> <name>OGChipConfigPath</name>
<state>$TOOLKIT_DIR$\config\devices\Texas Instruments\CC2530F256.i51</state> <state>$TOOLKIT_DIR$\config\devices\Texas Instruments\CC25xx\3x\CC2530F256.i51</state>
</option> </option>
</data> </data>
</settings> </settings>
@@ -8461,7 +8461,7 @@
<option> <option>
<name>Compiler Extra Options Edit</name> <name>Compiler Extra Options Edit</name>
<state>-f $PROJ_DIR$\..\..\..\Tools\CC2530DB\f8wRouter.cfg</state> <state>-f $PROJ_DIR$\..\..\..\Tools\CC2530DB\f8wRouter.cfg</state>
<state>-f $PROJ_DIR$\..\..\..\Tools\CC2530DB\f8wConfig.cfg</state> <state>-f $PROJ_DIR$\..\zstack-lib\f8wConfig.cfg</state>
<state>-f $PROJ_DIR$\..\..\..\Tools\CC2530DB\f8wZCL.cfg</state> <state>-f $PROJ_DIR$\..\..\..\Tools\CC2530DB\f8wZCL.cfg</state>
</option> </option>
<option> <option>
@@ -9687,7 +9687,7 @@
<name>$PROJ_DIR$\..\..\..\Tools\CC2530DB\f8w2530.xcl</name> <name>$PROJ_DIR$\..\..\..\Tools\CC2530DB\f8w2530.xcl</name>
</file> </file>
<file> <file>
<name>$PROJ_DIR$\..\..\..\Tools\CC2530DB\f8wConfig.cfg</name> <name>$PROJ_DIR$\..\zstack-lib\f8wConfig.cfg</name>
</file> </file>
<file> <file>
<name>$PROJ_DIR$\..\..\..\Tools\CC2530DB\f8wCoord.cfg</name> <name>$PROJ_DIR$\..\..\..\Tools\CC2530DB\f8wCoord.cfg</name>

36
README-RGB.md Normal file
View File

@@ -0,0 +1,36 @@
# Zintercom
## Firmware options
Each firmware version has 6 variants.
For different zigbee modules and power supply.
- EndDevice - for battery power
- Router - for external power
- PA1 - for E18-MS1PA1 module
- PA2 - for E18-MS1PA2 module
- no suffix - for E18-MS1 module
## Using battery as power supply
The firmware for the battery has the following differences.
- The device is mostly asleep.
- Wakes up once every 30 minutes (parameter - time_report) and sends a report.
- Zigbee commands are only executed when the device wakes up.
- RGB lights up for 2 seconds after changing the mode with the button.
- When the "no sound" mode is turned on, the constant consumption is 3 mA. In this mode AAA batteries will last 1-2 months.
## RGB Software
Release 2.0.0 support new RGB hardware and legacy hardware with one Led.
## RGB Hardware
Schematics and PCB - https://oshwlab.com/Utyf/zcom
![](hardware/Schematic_Zintercom_rgb.png)
![](images/front_side_rgb.png)
### Files to reproduce
* [Gerbers](https://github.com/diyruz/Zintercom/tree/master/hardware)
* [Firmware](https://github.com/diyruz/Zintercom/releases)

View File

@@ -1,29 +1,65 @@
# Zintercom # Zintercom
[![GitHub version](https://img.shields.io/github/release/xyzroe/Zintercom.svg)](https://github.com/xyzroe/Zintercom/releases)
[![GitHub download](https://img.shields.io/github/downloads/xyzroe/Zintercom/total.svg)](https://github.com/xyzroe/Zintercom/latest)
[![License](https://img.shields.io/github/license/xyzroe/Zintercom.svg)](LICENSE.txt)
## How to compile
Follow this article https://zigdevwiki.github.io/Begin/IAR_install/
##### Zigbee Intercom Automator ##### Zigbee Intercom Automator
This device is designed to control the matrix intercom using Zigbee. This device is designed to control the matrix intercom using Zigbee.
Using zigbee2mqtt you can: Using zigbee2mqtt you can:
1. Receive notification when the intercom rings. (also support **direct bind**) 1. Receive a notification when the intercom rings. (also support **direct bind**)
2. Mute the sound on the intercom handset. 2. Mute the sound on the intercom handset.
3. Automatically or manually open the door or hang up when the intercom rings. 3. Automatically or manually open the door or hang up when the intercom rings.
There are 4 work modes: There are 4 work modes:
1. `Never` - ordinary work mode, use handset to control 1. `Never` - ordinary work mode, use a handset to control
2. `Once` - one time open door when intercom rings 2. `Once` - one-time open door when intercom rings
3. `Always` - open door when intercom rings 3. `Always` - open door when intercom rings
4. `Drop` - hangs up all intercom rings, right after start 4. `Drop` - hangs up all intercom rings, right after the start
You can change the operating mode uisng z2m or by short press the button. (< 1000ms) You can change the operating mode using z2m or by short press the button. (< 1000ms)
After pressing the button, the LED will flash at 4 Hz. After pressing the button, the LED will flash at 4 Hz.
The number of flashes indicates the current operating mode. The number of flashes indicates the current operating mode.
You can control sound mode using z2m or by long press the button. (1000ms < X < 5000ms) You can control sound mode using z2m or by long-press the button. (1000ms < X < 5000ms)
After pressing the button, the LED will flash at 1.5 Hz. After pressing the button, the LED will flash at 1.5 Hz.
One flash - OFF, two flashes - ON. One flash - OFF, two flashes - ON.
## Hardware v2.0
New version of the board with RGB led support.
All known bugs and shortcomings have been fixed.
Thanks [@Utyff](https://github.com/Utyff)
### [More info](https://github.com/diyruz/Zintercom/blob/master/README-RGB.md)
## Important info
#### 1
In Gerber PCB v1.0 committed on Apr 14, there are some errors in the silkscreen layers:
1. 'Line-' and 'Phone-' are reversed.
2. '+' and '-' are also reversed.
Just plug by swapping.
#### 2
The problem of cross-calls to other apartments:
it was revealed that the intercom circuit is closed through the reverse diode of the u2 transistor (thanks to @Alex_AW)
to prevent it, you need to add a diode according to the diagram:
![](/images/fix_error_rings.png)
#### 3
If you want to use the battery version without a handset, do not turn off the sound in z2m, but use an external resistor to emulate the intercom handset, according to the diagram:
![](/images/battery_no_handset.png)
### How to join ### How to join
Reset to FN by reboot device 5 times with interval less than 10 seconds. Reset to FN by reboot the device 5 times with intervals of less than 10 seconds.
Reset to FN by press and hold BTN for 5 seconds. Reset to FN by pressing and holding BTN for 5 seconds.
LED will flash during reset. LED will flash during reset.
@@ -50,6 +86,8 @@ Converter file located [here](https://github.com/diyruz/Zintercom/blob/master/co
### DC Power ### DC Power
5-10 V
Support `router` and `end device` modes. Support `router` and `end device` modes.
Install `E18-MS1PA1`, `E18-MS1PA2` or `E18-MS1-PCB`. Install `E18-MS1PA1`, `E18-MS1PA2` or `E18-MS1-PCB`.
@@ -60,13 +98,15 @@ Install `E18-MS1PA1`, `E18-MS1PA2` or `E18-MS1-PCB`.
### Battery Power ### Battery Power
2 * AAA batteries
Support only `end device` mode. Support only `end device` mode.
Install `E18-MS1-PCB` only! Install `E18-MS1-PCB` only!
Do not turn off `sound` because it turns U2 forever, which will drain the battery much faster. Do not turn off `sound` because it turns U2 forever, which will drain the battery much faster.
Since the device is in sleep mode, it cannot receive commands. Since the device is in sleep mode, it cannot receive commands.
But you have the ability to set the button mode or at the time of the call. But you can set the button mode or at the time of the call.
If any commands are in the coordinator's queue, they will be executed after a button is pressed or a call is received. If any commands are in the coordinator's queue, they will be executed after a button is pressed or a call is received.
@@ -75,7 +115,7 @@ If any commands are in the coordinator's queue, they will be executed after a bu
##### The mode set by the Zigbee command `overwrites` the mode set by the button. ##### The mode set by the Zigbee command `overwrites` the mode set by the button.
### Binding ### Binding
The device supports direct binding of an incoming call to the onOff cluster. The device supports the direct binding of an incoming call to the onOff cluster.
For example, you can turn on the light while a call comes to the intercom, for notification in mute mode. For example, you can turn on the light while a call comes to the intercom, for notification in mute mode.
@@ -83,6 +123,12 @@ For example, you can turn on the light while a call comes to the intercom, for n
### Files to reproduce ### Files to reproduce
* [Gerbers and BOM](https://github.com/diyruz/Zintercom/tree/master/hardware) by [xyzroe](https://t.me/xyzroe) * [Gerbers and BOM](https://github.com/diyruz/Zintercom/tree/master/hardware) by [xyzroe](https://t.me/xyzroe)
* [Firmware](https://github.com/diyruz/Zintercom/releases) by [xyzroe](https://t.me/xyzroe) * [Firmware](https://github.com/diyruz/Zintercom/releases) by [xyzroe](https://t.me/xyzroe)
* [Case stl](https://www.thingiverse.com/thing:4866356) by [dreamertwo](https://t.me/dreamertwo)
![](https://cdn.thingiverse.com/assets/0b/2f/09/d3/37/large_display_2021-05-22_22-55-43.JPG)
### Like ♥️?
[!["Buy Me A Coffee"](https://www.buymeacoffee.com/assets/img/custom_images/orange_img.png)](https://www.buymeacoffee.com/xyzroe)
### Inspired by ### Inspired by

View File

@@ -61,30 +61,44 @@
#define HAL_LED_BLINK_DELAY() st( { volatile uint32 i; for (i=0; i<0x5800; i++) { }; } ) #define HAL_LED_BLINK_DELAY() st( { volatile uint32 i; for (i=0; i<0x5800; i++) { }; } )
#if defined(HAL_BOARD_TARGET) #if defined(HAL_BOARD_TARGET)
//led // blue
#define LED1_BV BV(4) #define LED1_BV BV(7)
#define LED1_SBIT P0_4 #define LED1_SBIT P1_7
#define LED1_DDR P0DIR #define LED1_DDR P1DIR
#define LED1_POLARITY ACTIVE_HIGH #define LED1_POLARITY ACTIVE_HIGH
//catch // green
#define LED2_BV BV(1) #define LED2_BV BV(6)
#define LED2_SBIT P0_1 #define LED2_SBIT P1_6
#define LED2_DDR P0DIR #define LED2_DDR P1DIR
#define LED2_POLARITY ACTIVE_HIGH #define LED2_POLARITY ACTIVE_HIGH
//answer // red
#define LED3_BV BV(2) #define LED3_BV BV(5)
#define LED3_SBIT P0_2 #define LED3_SBIT P1_5
#define LED3_DDR P0DIR #define LED3_DDR P1DIR
#define LED3_POLARITY ACTIVE_HIGH #define LED3_POLARITY ACTIVE_HIGH
//handset // old led
#define LED4_BV BV(3) #define LED4_BV BV(4)
#define LED4_SBIT P0_3 #define LED4_SBIT P0_4
#define LED4_DDR P0DIR #define LED4_DDR P0DIR
#define LED4_POLARITY ACTIVE_HIGH #define LED4_POLARITY ACTIVE_HIGH
// Catch control pin
#define CATCH_BV BV(1)
#define CATCH_PIN P0_1
#define CATCH_DDR P0DIR
#define CATCH_SSR P0SEL
// Answer control pin
#define ANSWER_BV BV(2)
#define ANSWER_PIN P0_2
#define ANSWER_DDR P0DIR
#define ANSWER_SSR P0SEL
// Handset control pin
#define HANDSET_BV BV(3)
#define HANDSET_PIN P0_3
#define HANDSET_DDR P0DIR
#define HANDSET_SSR P0SEL
#elif defined(HAL_BOARD_CHDTECH_DEV) #elif defined(HAL_BOARD_CHDTECH_DEV)
//blue//d3 //blue//d3
#define LED1_BV BV(4) #define LED1_BV BV(4)
#define LED1_SBIT P1_4 #define LED1_SBIT P1_4
#define LED1_DDR P1DIR #define LED1_DDR P1DIR
@@ -100,13 +114,33 @@
#define LED3_DDR P1DIR #define LED3_DDR P1DIR
#define LED3_POLARITY ACTIVE_LOW #define LED3_POLARITY ACTIVE_LOW
//ex //ex
#define LED4_BV BV(5) #define LED4_BV BV(4)
#define LED4_SBIT P1_5 #define LED4_SBIT P0_4
#define LED4_DDR P1DIR #define LED4_DDR P0DIR
#define LED4_POLARITY ACTIVE_LOW #define LED4_POLARITY ACTIVE_HIGH
// Catch control pin
#define CATCH_BV BV(1)
#define CATCH_PIN P0_1
#define CATCH_DDR P0DIR
#define CATCH_SSR P0SEL
// Answer control pin
#define ANSWER_BV BV(2)
#define ANSWER_PIN P1_2
#define ANSWER_DDR P1DIR
#define ANSWER_SSR P1SEL
// Handset control pin
#define HANDSET_BV BV(3)
#define HANDSET_PIN P1_3
#define HANDSET_DDR P1DIR
#define HANDSET_SSR P1SEL
#endif #endif
#define BLUE_LED HAL_LED_1
#define GREEN_LED HAL_LED_2
#define RED_LED HAL_LED_3
#define OLD_LED HAL_LED_4
#define INFO_LED HAL_LED_1 | HAL_LED_4
/* ------------------------------------------------------------------------------------------------ /* ------------------------------------------------------------------------------------------------
* Push Button Configuration * Push Button Configuration

View File

@@ -42,24 +42,33 @@
#endif #endif
#if defined( HAL_BOARD_TARGET ) #if defined( HAL_BOARD_TARGET )
// Income ring - P0_0
#define KEY_INCOME_PORT HAL_KEY_PORT0
#define HAL_KEY_P0_INPUT_PINS BV(0) #define HAL_KEY_P0_INPUT_PINS BV(0)
#define HAL_KEY_P0_INPUT_PINS_EDGE HAL_KEY_RISING_EDGE #define HAL_KEY_P0_INPUT_PINS_EDGE HAL_KEY_RISING_EDGE
// Button - P2_0
#define KEY1_PORT HAL_KEY_PORT2
#define HAL_KEY_P2_INPUT_PINS BV(0) #define HAL_KEY_P2_INPUT_PINS BV(0)
#define HAL_KEY_P2_INPUT_PINS_EDGE HAL_KEY_FALLING_EDGE #define HAL_KEY_P2_INPUT_PINS_EDGE HAL_KEY_FALLING_EDGE
#define INT_HEAP_LEN 2200//2256 #define INT_HEAP_LEN 2200//2256
#elif defined( HAL_BOARD_CHDTECH_DEV ) #elif defined( HAL_BOARD_CHDTECH_DEV )
// Income ring - P0_1
#define KEY_INCOME_PORT HAL_KEY_PORT0
#define HAL_KEY_P0_INPUT_PINS BV(1) #define HAL_KEY_P0_INPUT_PINS BV(1)
#define HAL_KEY_P0_INPUT_PINS_EDGE HAL_KEY_FALLING_EDGE #define HAL_KEY_P0_INPUT_PINS_EDGE HAL_KEY_FALLING_EDGE
// Button - P2_0
#define KEY1_PORT HAL_KEY_PORT2
#define HAL_KEY_P2_INPUT_PINS BV(0) #define HAL_KEY_P2_INPUT_PINS BV(0)
#define HAL_KEY_P2_INPUT_PINS_EDGE HAL_KEY_FALLING_EDGE #define HAL_KEY_P2_INPUT_PINS_EDGE HAL_KEY_FALLING_EDGE
#define DO_DEBUG_UART #define DO_DEBUG_UART
#define INT_HEAP_LEN 2060 #define INT_HEAP_LEN 2060
#endif #endif
#define FACTORY_RESET_HOLD_TIME_LONG 5000 #define BTN_HOLD_TIME 2000
#define FACTORY_RESET_HOLD_TIME_LONG 10000
#if defined( DO_DEBUG_UART ) #if defined( DO_DEBUG_UART )
#define HAL_UART_ISR 2 #define HAL_UART_ISR 0
#define HAL_UART TRUE #define HAL_UART TRUE
#define HAL_UART_DMA 1 #define HAL_UART_DMA 1
#endif #endif

View File

@@ -58,6 +58,14 @@
* GLOBAL VARIABLES * GLOBAL VARIABLES
*/ */
byte zclApp_TaskID; byte zclApp_TaskID;
#if defined( ZIC_BATTERY_MODE )
static byte isRingOn = false;
static byte isLedOn = false;
#endif
// for Old LED
static byte showMode = false;
static byte showSound = false;
/********************************************************************* /*********************************************************************
* GLOBAL FUNCTIONS * GLOBAL FUNCTIONS
@@ -77,16 +85,17 @@ static void zclApp_BasicResetCB(void);
static void zclApp_RestoreAttributesFromNV(void); static void zclApp_RestoreAttributesFromNV(void);
static void zclApp_SaveAttributesToNV(void); static void zclApp_SaveAttributesToNV(void);
static void zclApp_HandleKeys(byte portAndAction, byte keyCode); static void zclApp_HandleKeys(byte portAndAction, byte keyCode);
static void zclApp_ControlPinsInit(void);
static ZStatus_t zclApp_ReadWriteAuthCB(afAddrType_t *srcAddr, zclAttrRec_t *pAttr, uint8 oper); static ZStatus_t zclApp_ReadWriteAuthCB(afAddrType_t *srcAddr, zclAttrRec_t *pAttr, uint8 oper);
static void zclApp_Report(void);
static void zclApp_OneReport(void); static void zclApp_OneReport(void);
static void zclApp_ConfigInit(bool restart); static void zclApp_ConfigInit(bool restart);
static void zclApp_BtnClick(bool hold); static void zclApp_BtnClicks(byte count);
static void zclApp_RingRun(void); static void zclApp_RingRun(void);
static void zclApp_TalkStart(void); static void zclApp_TalkStart(void);
static void zclApp_RingEnd(void); static void zclApp_RingEnd(void);
static void zclApp_WorkWithLEDs(void);
/********************************************************************* /*********************************************************************
* ZCL General Profile Callback table * ZCL General Profile Callback table
@@ -101,9 +110,8 @@ static zclGeneral_AppCallbacks_t zclApp_CmdCallbacks = {
NULL, // RSSI Location command NULL, // RSSI Location command
NULL // RSSI Location Response command NULL // RSSI Location Response command
}; };
void zclApp_Init(byte task_id) {
//HalLedSet(HAL_LED_ALL, HAL_LED_MODE_BLINK);
void zclApp_Init(byte task_id) {
zclApp_RestoreAttributesFromNV(); zclApp_RestoreAttributesFromNV();
zclApp_TaskID = task_id; zclApp_TaskID = task_id;
@@ -122,6 +130,8 @@ void zclApp_Init(byte task_id) {
zclApp_ConfigInit(TIMER_START); zclApp_ConfigInit(TIMER_START);
zclApp_ControlPinsInit();
IO_IMODE_PORT_PIN(0,0,IO_TRI); IO_IMODE_PORT_PIN(0,0,IO_TRI);
#if defined( ZIC_BATTERY_MODE ) #if defined( ZIC_BATTERY_MODE )
@@ -129,65 +139,69 @@ void zclApp_Init(byte task_id) {
#endif #endif
} }
static void zclApp_ControlPinsInit (void) {
CATCH_SSR &= ~CATCH_BV; // Set PIN as general I/O port functions
CATCH_DDR |= CATCH_BV; // Set the port transmission mode for PIN to output
ANSWER_SSR &= ~ANSWER_BV;
ANSWER_DDR |= ANSWER_BV;
HANDSET_SSR &= ~HANDSET_BV;
HANDSET_DDR |= HANDSET_BV;
P0SEL &= ~0x01; // Set P0_0 as general I/O port function
P0DIR &= ~0x01; // Set the port transmission mode of P0_0 to input
// ? P0INP &= ~0x01; //Set the port input mode of P0_0 to: pull up/down
}
static void zclApp_HandleKeys(byte portAndAction, byte keyCode) { static void zclApp_HandleKeys(byte portAndAction, byte keyCode) {
//LREP("zclApp_HandleKeys portAndAction=0x%X keyCode=0x%X\r\n", portAndAction, keyCode); if (portAndAction & KEY_INCOME_PORT) { //P0 Ring //S1 P0_1 TODO add check Income pin
//zclCommissioning_HandleKeys(portAndAction, keyCode); //exit old stop timer
osal_stop_timerEx(zclApp_TaskID, APP_RING_STOP_EVT);
if (portAndAction & 0x01) { //P0 Ring //S1 P0_1 osal_start_timerEx(zclApp_TaskID, APP_RING_STOP_EVT, zclApp_Config.TimeBell * 1000);
if (portAndAction & HAL_KEY_PRESS) { if (portAndAction & HAL_KEY_PRESS) {
//start ring
//exit old stop timer if (zclApp_State.State == Idle) {
osal_stop_timerEx(zclApp_TaskID, APP_RING_STOP_EVT);
//osal_clear_event(zclApp_TaskID, APP_RING_STOP_EVT);
//start new stop timer (ring ends timer)
osal_start_timerEx(zclApp_TaskID, APP_RING_STOP_EVT, 3000);
//start ring
if (zclApp_State.RingRunStep == 0) {
#if defined( ZIC_BATTERY_MODE ) #if defined( ZIC_BATTERY_MODE )
osal_pwrmgr_task_state(zclApp_TaskID, PWRMGR_HOLD); osal_pwrmgr_task_state(zclApp_TaskID, PWRMGR_HOLD);
isRingOn = true;
#endif #endif
LREPMaster("Ring start\r\n"); LREPMaster("Ring start\r\n");
//HalLedSet(LED_PIN, HAL_LED_MODE_BLINK); osal_start_timerEx(zclApp_TaskID, APP_RING_RUN_EVT, 50);
zclApp_State.RingRunStep = 1;
osal_start_reload_timer(zclApp_TaskID, APP_RING_RUN_EVT, 500);
afAddrType_t inderect_DstAddr = {.addrMode = (afAddrMode_t)AddrNotPresent, .endPoint = 0, .addr.shortAddr = 0}; afAddrType_t inderect_DstAddr = {.addrMode = (afAddrMode_t)AddrNotPresent, .endPoint = 0, .addr.shortAddr = 0};
zclGeneral_SendOnOff_CmdOn(zclApp_FirstEP.EndPoint, &inderect_DstAddr, FALSE, bdb_getZCLFrameCounter()); zclGeneral_SendOnOff_CmdOn(zclApp_FirstEP.EndPoint, &inderect_DstAddr, FALSE, bdb_getZCLFrameCounter());
} }
} }
} }
if (portAndAction & 0x04) { //P2 Btn //S2 P2_0 if (portAndAction & KEY1_PORT) { //P2 Btn //S2 P2_0 TODO add check BUTTON pin
zclFactoryResetter_HandleKeys(portAndAction, keyCode); zclFactoryResetter_HandleKeys(portAndAction, keyCode);
if (portAndAction & HAL_KEY_PRESS) { if (portAndAction & HAL_KEY_PRESS) {
LREPMaster("Key pressed\r\n"); LREP("Key pressed. Clicks - %d\r\n", zclApp_State.clicks);
zclApp_State.pressTime = osal_getClock(); if (zclApp_State.clicks < 2) {
LREP("pressTime = %d\r\n", zclApp_State.pressTime); zclApp_State.clicks++;
}
osal_start_timerEx(zclApp_TaskID, APP_BTN_HOLD_EVT, BTN_HOLD_TIME);
osal_stop_timerEx(zclApp_TaskID, APP_BTN_CLICK_EVT);
} }
if (portAndAction & HAL_KEY_RELEASE) { if (portAndAction & HAL_KEY_RELEASE) {
LREPMaster("Key released\r\n"); LREPMaster("Key released\r\n");
uint32 holdTime = osal_getClock() - zclApp_State.pressTime;
LREP("holdTime = %d \r\n", holdTime); osal_stop_timerEx(zclApp_TaskID, APP_BTN_HOLD_EVT);
zclApp_State.pressTime = 0; if (zclApp_State.clicks == 1) {
if (holdTime >= 1) { //seconds osal_start_timerEx(zclApp_TaskID, APP_BTN_CLICK_EVT, 250);
osal_start_reload_timer(zclApp_TaskID, APP_BTN_HOLD_EVT, 50);
} }
else { if (zclApp_State.clicks == 2) {
osal_start_reload_timer(zclApp_TaskID, APP_BTN_CLICK_EVT, 50); osal_start_timerEx(zclApp_TaskID, APP_BTN_DOUBLE_EVT, 50);
} }
} }
} }
} }
uint16 zclApp_event_loop(uint8 task_id, uint16 events) { uint16 zclApp_event_loop(uint8 task_id, uint16 events) {
LREP("events 0x%x \r\n", events); LREP("events 0x%x \r\n", events);
if (events & SYS_EVENT_MSG) { if (events & SYS_EVENT_MSG) {
@@ -217,7 +231,7 @@ uint16 zclApp_event_loop(uint8 task_id, uint16 events) {
} }
if (events & APP_REPORT_EVT) { if (events & APP_REPORT_EVT) {
LREPMaster("APP_REPORT_EVT\r\n"); LREPMaster("APP_REPORT_EVT\r\n");
zclApp_Report(); zclApp_OneReport();
return (events ^ APP_REPORT_EVT); return (events ^ APP_REPORT_EVT);
} }
@@ -230,7 +244,7 @@ uint16 zclApp_event_loop(uint8 task_id, uint16 events) {
if (events & APP_BTN_CLICK_EVT) { if (events & APP_BTN_CLICK_EVT) {
LREPMaster("APP_BTN_CLICK_EVT\r\n"); LREPMaster("APP_BTN_CLICK_EVT\r\n");
zclApp_BtnClick(false); zclApp_BtnClicks(1);
return (events ^ APP_BTN_CLICK_EVT); return (events ^ APP_BTN_CLICK_EVT);
} }
@@ -242,7 +256,10 @@ uint16 zclApp_event_loop(uint8 task_id, uint16 events) {
if (events & APP_RING_STOP_EVT) { if (events & APP_RING_STOP_EVT) {
LREPMaster("APP_RING_STOP_EVT\r\n"); LREPMaster("APP_RING_STOP_EVT\r\n");
zclApp_RingEnd(); // if answer started - break not allowed
if (zclApp_State.State == Ring) {
zclApp_RingEnd();
}
return (events ^ APP_RING_STOP_EVT); return (events ^ APP_RING_STOP_EVT);
} }
@@ -252,90 +269,97 @@ uint16 zclApp_event_loop(uint8 task_id, uint16 events) {
return (events ^ APP_TALK_START_EVT); return (events ^ APP_TALK_START_EVT);
} }
if (events & APP_WORK_LED_EVT) {
LREPMaster("APP_WORK_LED_EVT\r\n");
zclApp_WorkWithLEDs();
return (events ^ APP_WORK_LED_EVT);
}
if (events & APP_BTN_HOLD_EVT) { if (events & APP_BTN_HOLD_EVT) {
LREPMaster("APP_BTN_HOLD_EVT\r\n"); LREPMaster("APP_BTN_HOLD_EVT\r\n");
zclApp_BtnClick(true); //#if !defined( ZIC_BATTERY_MODE )
zclApp_BtnClicks(255);
//#endif
return (events ^ APP_BTN_HOLD_EVT); return (events ^ APP_BTN_HOLD_EVT);
} }
if (events & APP_BTN_DOUBLE_EVT) {
LREPMaster("APP_BTN_DOUBLE_EVT\r\n");
zclApp_BtnClicks(2);
return (events ^ APP_BTN_DOUBLE_EVT);
}
return 0; return 0;
} }
static void zclApp_RingRun(void) { static void zclApp_RingRun(void) {
zclApp_State.RingRunStep++;
LREP("zclApp_State.RingRunStep %d\r\n", zclApp_State.RingRunStep);
LREP("zclApp_State.State %d\r\n", zclApp_State.State); LREP("zclApp_State.State %d\r\n", zclApp_State.State);
uint32 timeRingStart = osal_GetSystemClock();
// timeout for next ring step
// 250 - default ring timeout in Never mode
uint32 timeout_value = 250;
switch (zclApp_State.State) { switch (zclApp_State.State) {
case Idle: case Idle:
zclApp_State.State = Ring; zclApp_State.State = Ring;
if (zclApp_Config.ModeOpen != Never) {
timeout_value = zclApp_Config.TimeRing * 1000;
}
zclApp_OneReport(); zclApp_OneReport();
break; break;
case Ring: case Ring:
if ((zclApp_Config.ModeOpen == Once) || (zclApp_Config.ModeOpen == Always)){ if (zclApp_Config.ModeOpen == Never) {
if (zclApp_State.RingRunStep > (zclApp_Config.TimeRing * 2)) { break;
zclApp_State.State = Talk;
zclApp_TalkStart();
}
} }
if (zclApp_Config.ModeOpen == Drop){ zclApp_State.State = Talk;
zclApp_State.State = Droped; timeout_value = zclApp_Config.TimeTalk * 1000;
zclApp_TalkStart(); zclApp_TalkStart();
} break;
break;
case Talk: case Talk:
osal_stop_timerEx(zclApp_TaskID, APP_RING_STOP_EVT); osal_stop_timerEx(zclApp_TaskID, APP_RING_STOP_EVT);
if ((zclApp_Config.ModeOpen == Once) || (zclApp_Config.ModeOpen == Always)){ if (zclApp_Config.ModeOpen == Once || zclApp_Config.ModeOpen == Always) {
if (zclApp_State.RingRunStep > ((zclApp_Config.TimeRing + zclApp_Config.TimeTalk) * 2)) { // open door
zclApp_State.State = Open; timeout_value = zclApp_Config.TimeOpen * 1000;
HalLedSet(ANSWER_PIN, HAL_LED_MODE_OFF); zclApp_State.State = Open;
zclApp_OneReport(); ANSWER_PIN = 0;
} zclApp_OneReport();
break;
} }
break; // No break here. End call without open
case Open: case Open:
// end call
osal_stop_timerEx(zclApp_TaskID, APP_RING_STOP_EVT); osal_stop_timerEx(zclApp_TaskID, APP_RING_STOP_EVT);
if ((zclApp_Config.ModeOpen == Once) || (zclApp_Config.ModeOpen == Always)){ zclApp_RingEnd();
if (zclApp_State.RingRunStep > ((zclApp_Config.TimeRing + zclApp_Config.TimeTalk + zclApp_Config.TimeOpen) * 2)) { timeout_value = 0;
zclApp_RingEnd(); break;
}
}
break;
case Droped:
if (zclApp_State.RingRunStep > 1) {
zclApp_RingEnd();
}
break;
} }
if (timeout_value != 0) {
osal_start_timerEx(zclApp_TaskID, APP_RING_RUN_EVT, timeout_value);
}
osal_start_timerEx(zclApp_TaskID, APP_WORK_LED_EVT, 50);
} }
static void zclApp_TalkStart(void) { static void zclApp_TalkStart(void) {
LREPMaster("Talk start\r\n"); LREPMaster("Talk start\r\n");
osal_stop_timerEx(zclApp_TaskID, APP_RING_STOP_EVT);
//osal_clear_event(zclApp_TaskID, APP_RING_STOP_EVT);
zclApp_OneReport(); zclApp_OneReport();
HalLedSet(ANSWER_PIN, HAL_LED_MODE_ON); ANSWER_PIN = 1;
if (zclApp_Config.ModeSound == true) { if (zclApp_Config.ModeSound == true) {
HalLedSet(HANDSET_PIN, HAL_LED_MODE_ON); HANDSET_PIN = 1;
} }
else { else {
HalLedSet(CATCH_PIN, HAL_LED_MODE_OFF); CATCH_PIN = 0;
} }
} }
static void zclApp_RingEnd(void) { static void zclApp_RingEnd(void) {
LREPMaster("Ring end\r\n"); LREPMaster("Ring end\r\n");
HalLedSet(CATCH_PIN, !zclApp_Config.ModeSound); CATCH_PIN = !zclApp_Config.ModeSound;
HalLedSet(HANDSET_PIN, !zclApp_Config.ModeSound); HANDSET_PIN = !zclApp_Config.ModeSound;
HalLedSet(ANSWER_PIN, HAL_LED_MODE_OFF); ANSWER_PIN = 0;
osal_stop_timerEx(zclApp_TaskID, APP_RING_RUN_EVT); osal_stop_timerEx(zclApp_TaskID, APP_RING_RUN_EVT);
osal_clear_event(zclApp_TaskID, APP_RING_RUN_EVT); osal_start_timerEx(zclApp_TaskID, APP_WORK_LED_EVT, 50);
osal_stop_timerEx(zclApp_TaskID, APP_RING_STOP_EVT);
//osal_clear_event(zclApp_TaskID, APP_RING_STOP_EVT);
zclApp_State.RingRunStep = 0;
zclApp_State.State = Idle; zclApp_State.State = Idle;
afAddrType_t inderect_DstAddr = {.addrMode = (afAddrMode_t)AddrNotPresent, .endPoint = 0, .addr.shortAddr = 0}; afAddrType_t inderect_DstAddr = {.addrMode = (afAddrMode_t)AddrNotPresent, .endPoint = 0, .addr.shortAddr = 0};
@@ -348,69 +372,134 @@ static void zclApp_RingEnd(void) {
#if defined( ZIC_BATTERY_MODE ) #if defined( ZIC_BATTERY_MODE )
zclBattery_Report(); zclBattery_Report();
osal_pwrmgr_task_state(zclApp_TaskID, PWRMGR_CONSERVE); isRingOn = false;
#endif if (isLedOn == false) {
osal_pwrmgr_task_state(zclApp_TaskID, PWRMGR_CONSERVE);
}
#endif
} }
static void zclApp_BtnClick(bool hold) { static void zclApp_WorkWithLEDs(void) {
#if defined( ZIC_BATTERY_MODE )
static uint8 currentBtnClickPhase = 0; if (isLedOn != false) { // Off LEDs and goto sleep
LREP("currentBtnClickPhase %d\r\n", currentBtnClickPhase); isLedOn = false;
switch (currentBtnClickPhase++) { HalLedSet(HAL_LED_ALL, HAL_LED_MODE_OFF);
case 0: if (isRingOn == false) {
if (hold) { osal_pwrmgr_task_state(zclApp_TaskID, PWRMGR_CONSERVE);
#if !defined( ZIC_BATTERY_MODE ) }
zclApp_Config.ModeSound = !zclApp_Config.ModeSound; return;
HalLedSet(HANDSET_PIN, !zclApp_Config.ModeSound); }
HalLedSet(CATCH_PIN, !zclApp_Config.ModeSound); // On LEDs and hold power 2 sec.
#endif isLedOn = true;
osal_pwrmgr_task_state(zclApp_TaskID, PWRMGR_HOLD);
osal_start_timerEx(zclApp_TaskID, APP_WORK_LED_EVT, 2000);
#endif
if (showSound & showMode) {
showSound = false;
showMode = false;
HalLedBlink(OLD_LED, 1, 99, 2000);
} else if (showSound) {
showSound = false;
HalLedBlink(OLD_LED, zclApp_Config.ModeSound + 1, 50, 750);
} else if (showMode) {
showMode = false;
HalLedBlink(OLD_LED, zclApp_Config.ModeOpen + 1, 50, 250);
}
if (zclApp_Config.ModeOpen == Always) {
HalLedSet(GREEN_LED, HAL_LED_MODE_ON);
}
if (zclApp_Config.ModeOpen != Always) {
HalLedSet(GREEN_LED, HAL_LED_MODE_OFF);
}
if (zclApp_Config.ModeOpen == Once) {
HalLedBlink(GREEN_LED, 0, 95, 500);
}
if (zclApp_Config.ModeOpen == Drop) {
HalLedSet(RED_LED, HAL_LED_MODE_ON);
}
if (zclApp_Config.ModeOpen != Drop) {
HalLedSet(RED_LED, HAL_LED_MODE_OFF);
}
if (zclApp_State.State != Idle) {
HalLedSet(RED_LED, HAL_LED_MODE_BLINK);
}
if (zclApp_Config.ModeSound == true) {
HalLedSet(BLUE_LED, HAL_LED_MODE_OFF);
}
else {
HalLedSet(BLUE_LED, HAL_LED_MODE_ON);
}
}
static void zclApp_BtnClicks(byte count) {
zclApp_State.clicks = 0;
osal_start_timerEx(zclApp_TaskID, APP_WORK_LED_EVT, 50);
switch (count) {
case 1:
LREPMaster("Button click\r\n");
if (zclApp_State.State == Idle) {
// if we don`t have income ring - change mode
if (zclApp_Config.ModeOpen < Drop) {
zclApp_Config.ModeOpen++;
}
else {
zclApp_Config.ModeOpen = Never;
}
zclApp_OneReport();
} }
else { else {
if (zclApp_Config.ModeOpen < Drop) { // if we have income ring, and mode is Never - open door
zclApp_Config.ModeOpen++; if (zclApp_State.State == Ring && zclApp_Config.ModeOpen == Never) {
} zclApp_Config.ModeOpen = Once;
else { }
zclApp_Config.ModeOpen = Never;
}
} }
break; showMode = true;
case 1:
zclApp_OneReport();
break; break;
case 2: case 2:
if (hold) { LREPMaster("Button double\r\n");
HalLedBlink(LED_PIN, zclApp_Config.ModeSound+1, 50, 750); if (zclApp_State.State == Idle) {
} zclApp_Config.ModeSound = !zclApp_Config.ModeSound;
else { HANDSET_PIN = !zclApp_Config.ModeSound;
HalLedBlink(LED_PIN, zclApp_Config.ModeOpen+1, 50, 250); CATCH_PIN = !zclApp_Config.ModeSound;
zclApp_OneReport();
} }
showSound = true;
break; break;
case 3: case 255:
if (hold) { LREPMaster("Button hold\r\n");
osal_stop_timerEx(zclApp_TaskID, APP_BTN_HOLD_EVT); if (zclApp_State.State == Idle) {
osal_clear_event(zclApp_TaskID, APP_BTN_HOLD_EVT); // if we don`t have income ring - reset mode
zclApp_Config.ModeSound = true;
HANDSET_PIN = !zclApp_Config.ModeSound;
CATCH_PIN = !zclApp_Config.ModeSound;
zclApp_Config.ModeOpen = Never;
zclApp_OneReport();
} }
else { else {
osal_stop_timerEx(zclApp_TaskID, APP_BTN_CLICK_EVT); // if we have income ring - drop it
osal_clear_event(zclApp_TaskID, APP_BTN_CLICK_EVT); if (zclApp_State.State == Ring) {
// in stage "ring" - start talk
osal_stop_timerEx(zclApp_TaskID, APP_RING_RUN_EVT);
osal_start_timerEx(zclApp_TaskID, APP_RING_RUN_EVT, zclApp_Config.TimeTalk * 1000);
zclApp_TalkStart();
}
// skip step "open", go to end call
zclApp_State.State = Open;
osal_start_timerEx(zclApp_TaskID, APP_RING_STOP_EVT, 250);
} }
currentBtnClickPhase = 0; showMode = true;
showSound = true;
break; break;
} }
} }
static void zclApp_Report(void) {
zclApp_OneReport();
}
static void zclApp_OneReport(void) { static void zclApp_OneReport(void) {
HalLedSet(LED_PIN, HAL_LED_MODE_BLINK);
bdb_RepChangedAttrValue(zclApp_FirstEP.EndPoint, ZCL_INTERCOM, ATTRID_STATE); bdb_RepChangedAttrValue(zclApp_FirstEP.EndPoint, ZCL_INTERCOM, ATTRID_STATE);
bdb_RepChangedAttrValue(zclApp_FirstEP.EndPoint, ZCL_INTERCOM, ATTRID_MODEOPEN); bdb_RepChangedAttrValue(zclApp_FirstEP.EndPoint, ZCL_INTERCOM, ATTRID_MODEOPEN);
#if !defined( ZIC_BATTERY_MODE ) bdb_RepChangedAttrValue(zclApp_FirstEP.EndPoint, ZCL_INTERCOM, ATTRID_MODESOUND);
bdb_RepChangedAttrValue(zclApp_FirstEP.EndPoint, ZCL_INTERCOM, ATTRID_MODESOUND);
#endif
} }
static void zclApp_BasicResetCB(void) { static void zclApp_BasicResetCB(void) {
@@ -421,7 +510,7 @@ static void zclApp_BasicResetCB(void) {
static ZStatus_t zclApp_ReadWriteAuthCB(afAddrType_t *srcAddr, zclAttrRec_t *pAttr, uint8 oper) { static ZStatus_t zclApp_ReadWriteAuthCB(afAddrType_t *srcAddr, zclAttrRec_t *pAttr, uint8 oper) {
LREPMaster("AUTH CB called\r\n"); LREPMaster("AUTH CB called\r\n");
osal_start_timerEx(zclApp_TaskID, APP_SAVE_ATTRS_EVT, 2000); osal_start_timerEx(zclApp_TaskID, APP_SAVE_ATTRS_EVT, 200);
return ZSuccess; return ZSuccess;
} }
@@ -439,10 +528,13 @@ static void zclApp_ConfigInit(bool restart) {
uint32 ReportInterval = (uint32)zclApp_Config.TimeReport * (uint32)60; uint32 ReportInterval = (uint32)zclApp_Config.TimeReport * (uint32)60;
LREP("Start report with interval %d seconds\r\n", ReportInterval); LREP("Start report with interval %d seconds\r\n", ReportInterval);
osal_start_reload_timer(zclApp_TaskID, APP_REPORT_EVT, ((uint32)ReportInterval*(uint32)1000)); osal_start_reload_timer(zclApp_TaskID, APP_REPORT_EVT, ((uint32)ReportInterval*(uint32)1000));
osal_start_timerEx(zclApp_TaskID, APP_WORK_LED_EVT, 50);
HalLedSet(HANDSET_PIN, !zclApp_Config.ModeSound);
HalLedSet(CATCH_PIN, !zclApp_Config.ModeSound); if (zclApp_State.State == Idle) {
HalLedSet(ANSWER_PIN, HAL_LED_MODE_OFF); HANDSET_PIN = !zclApp_Config.ModeSound;
CATCH_PIN = !zclApp_Config.ModeSound;
ANSWER_PIN = 0;
}
} }
static void zclApp_RestoreAttributesFromNV(void) { static void zclApp_RestoreAttributesFromNV(void) {

View File

@@ -24,6 +24,8 @@ extern "C" {
#define APP_BTN_HOLD_EVT 0x0010 #define APP_BTN_HOLD_EVT 0x0010
#define APP_RING_STOP_EVT 0x0020 #define APP_RING_STOP_EVT 0x0020
#define APP_TALK_START_EVT 0x0040 #define APP_TALK_START_EVT 0x0040
#define APP_WORK_LED_EVT 0x0080
#define APP_BTN_DOUBLE_EVT 0x0100
/********************************************************************* /*********************************************************************
* MACROS * MACROS
@@ -53,13 +55,9 @@ extern "C" {
#define ATTRID_TIMERING 0x0053 #define ATTRID_TIMERING 0x0053
#define ATTRID_TIMETALK 0x0054 #define ATTRID_TIMETALK 0x0054
#define ATTRID_TIMEOPEN 0x0055 #define ATTRID_TIMEOPEN 0x0055
#define ATTRID_TIMEBELL 0x0057
#define ATTRID_TIMEREPORT 0x0056 #define ATTRID_TIMEREPORT 0x0056
#define LED_PIN HAL_LED_1
#define CATCH_PIN HAL_LED_2
#define ANSWER_PIN HAL_LED_3
#define HANDSET_PIN HAL_LED_4
#define TIMER_RESTART TRUE #define TIMER_RESTART TRUE
#define TIMER_START FALSE #define TIMER_START FALSE
@@ -107,13 +105,14 @@ typedef struct {
uint8 TimeRing; uint8 TimeRing;
uint8 TimeTalk; uint8 TimeTalk;
uint8 TimeOpen; uint8 TimeOpen;
uint8 TimeBell;
uint8 TimeReport; uint8 TimeReport;
} application_config_t; } application_config_t;
typedef struct { typedef struct {
WorkState_t State; WorkState_t State;
uint8 RingRunStep;
uint32 pressTime; uint32 pressTime;
byte clicks;
} device_state_t; } device_state_t;

View File

@@ -67,7 +67,7 @@ const uint8 zclApp_PowerSource = POWER_SOURCE_DC;
#define DEFAULT_TimeRing 7 //seconds to ring, before answer #define DEFAULT_TimeRing 7 //seconds to ring, before answer
#define DEFAULT_TimeTalk 3 //seconds to talk, before open #define DEFAULT_TimeTalk 3 //seconds to talk, before open
#define DEFAULT_TimeOpen 2 //seconds to hold open #define DEFAULT_TimeOpen 2 //seconds to hold open
#define DEFAULT_TimeBell 3 //seconds after last bell to finish ring
application_config_t zclApp_Config = { application_config_t zclApp_Config = {
.ModeOpen = DEFAULT_ModeOpen, .ModeOpen = DEFAULT_ModeOpen,
@@ -75,12 +75,12 @@ application_config_t zclApp_Config = {
.TimeRing = DEFAULT_TimeRing, .TimeRing = DEFAULT_TimeRing,
.TimeTalk = DEFAULT_TimeTalk, .TimeTalk = DEFAULT_TimeTalk,
.TimeOpen = DEFAULT_TimeOpen, .TimeOpen = DEFAULT_TimeOpen,
.TimeBell = DEFAULT_TimeBell,
.TimeReport = DEFAULT_TimeReport, .TimeReport = DEFAULT_TimeReport,
}; };
device_state_t zclApp_State = { device_state_t zclApp_State = {
.State = Idle, .State = Idle,
.RingRunStep = 0,
.pressTime = 0, .pressTime = 0,
}; };
@@ -122,6 +122,7 @@ CONST zclAttrRec_t zclApp_AttrsFirstEP[] = {
{ZCL_INTERCOM, {ATTRID_TIMERING, ZCL_UINT8, RW, (void *)&zclApp_Config.TimeRing}}, {ZCL_INTERCOM, {ATTRID_TIMERING, ZCL_UINT8, RW, (void *)&zclApp_Config.TimeRing}},
{ZCL_INTERCOM, {ATTRID_TIMETALK, ZCL_UINT8, RW, (void *)&zclApp_Config.TimeTalk}}, {ZCL_INTERCOM, {ATTRID_TIMETALK, ZCL_UINT8, RW, (void *)&zclApp_Config.TimeTalk}},
{ZCL_INTERCOM, {ATTRID_TIMEOPEN, ZCL_UINT8, RW, (void *)&zclApp_Config.TimeOpen}}, {ZCL_INTERCOM, {ATTRID_TIMEOPEN, ZCL_UINT8, RW, (void *)&zclApp_Config.TimeOpen}},
{ZCL_INTERCOM, {ATTRID_TIMEBELL, ZCL_UINT8, RW, (void *)&zclApp_Config.TimeBell}},
{ZCL_INTERCOM, {ATTRID_TIMEREPORT, ZCL_UINT8, RW, (void *)&zclApp_Config.TimeReport}}, {ZCL_INTERCOM, {ATTRID_TIMEREPORT, ZCL_UINT8, RW, (void *)&zclApp_Config.TimeReport}},
}; };
@@ -157,5 +158,6 @@ void zclApp_ResetAttributesToDefaultValues(void) {
zclApp_Config.TimeRing = DEFAULT_TimeRing; zclApp_Config.TimeRing = DEFAULT_TimeRing;
zclApp_Config.TimeTalk = DEFAULT_TimeTalk; zclApp_Config.TimeTalk = DEFAULT_TimeTalk;
zclApp_Config.TimeOpen = DEFAULT_TimeOpen; zclApp_Config.TimeOpen = DEFAULT_TimeOpen;
zclApp_Config.TimeBell = DEFAULT_TimeBell;
zclApp_Config.TimeReport = DEFAULT_TimeReport; zclApp_Config.TimeReport = DEFAULT_TimeReport;
} }

View File

@@ -1,11 +1,12 @@
const { const zigbeeHerdsmanConverters = require('zigbee-herdsman-converters');
fromZigbeeConverters,
toZigbeeConverters, const exposes = zigbeeHerdsmanConverters['exposes'] || require("zigbee-herdsman-converters/lib/exposes");
exposes
} = require('zigbee-herdsman-converters');
const ep = exposes.presets; const ep = exposes.presets;
const ea = exposes.access; const ea = exposes.access;
const fromZigbeeConverters = zigbeeHerdsmanConverters.fromZigbeeConverters || zigbeeHerdsmanConverters.fromZigbee;
const toZigbeeConverters = zigbeeHerdsmanConverters.toZigbeeConverters || zigbeeHerdsmanConverters.toZigbee;
const bind = async (endpoint, target, clusters) => { const bind = async (endpoint, target, clusters) => {
for (const cluster of clusters) { for (const cluster of clusters) {
@@ -82,6 +83,9 @@ const fz = {
if (msg.data.hasOwnProperty(0x0055)) { if (msg.data.hasOwnProperty(0x0055)) {
result.time_open = msg.data[0x0055]; result.time_open = msg.data[0x0055];
} }
if (msg.data.hasOwnProperty(0x0057)) {
result.time_bell = msg.data[0x0057];
}
if (msg.data.hasOwnProperty(0x0056)) { if (msg.data.hasOwnProperty(0x0056)) {
result.time_report = msg.data[0x0056]; result.time_report = msg.data[0x0056];
} }
@@ -92,7 +96,7 @@ const fz = {
const tz = { const tz = {
diy_zintercom_config: { diy_zintercom_config: {
key: ['state', 'mode', 'sound', 'time_ring', 'time_talk', 'time_open', 'time_report'], key: ['state', 'mode', 'sound', 'time_ring', 'time_talk', 'time_open', 'time_bell', 'time_report'],
convertSet: async (entity, key, rawValue, meta) => { convertSet: async (entity, key, rawValue, meta) => {
const lookup = { const lookup = {
'OFF': 0x00, 'OFF': 0x00,
@@ -118,6 +122,7 @@ const tz = {
time_ring: {0x0053: {value, type: 0x20}}, time_ring: {0x0053: {value, type: 0x20}},
time_talk: {0x0054: {value, type: 0x20}}, time_talk: {0x0054: {value, type: 0x20}},
time_open: {0x0055: {value, type: 0x20}}, time_open: {0x0055: {value, type: 0x20}},
time_bell: {0x0057: {value, type: 0x20}},
time_report: {0x0056: {value, type: 0x20}}, time_report: {0x0056: {value, type: 0x20}},
}; };
@@ -134,6 +139,7 @@ const tz = {
time_ring: ['closuresDoorLock', 0x0053], time_ring: ['closuresDoorLock', 0x0053],
time_talk: ['closuresDoorLock', 0x0054], time_talk: ['closuresDoorLock', 0x0054],
time_open: ['closuresDoorLock', 0x0055], time_open: ['closuresDoorLock', 0x0055],
time_bell: ['closuresDoorLock', 0x0057],
time_report: ['closuresDoorLock', 0x0056], time_report: ['closuresDoorLock', 0x0056],
}; };
await entity.read(payloads[key][0], [payloads[key][1]]); await entity.read(payloads[key][0], [payloads[key][1]]);
@@ -193,10 +199,11 @@ const device = {
.withDescription('Time to hold before open'), .withDescription('Time to hold before open'),
exposes.numeric('time_open', ea.ALL).withUnit('sec') exposes.numeric('time_open', ea.ALL).withUnit('sec')
.withDescription('Time to open before end'), .withDescription('Time to open before end'),
exposes.numeric('time_bell', ea.ALL).withUnit('sec')
.withDescription('Time after last bell to finish ring'),
exposes.numeric('time_report', ea.ALL).withUnit('min') exposes.numeric('time_report', ea.ALL).withUnit('min')
.withDescription('Reporting interval'), .withDescription('Reporting interval'),
ep.battery(), ep.battery(),
ep.linkquality(),
], ],
}; };

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 206 KiB

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 76 KiB

BIN
images/fix_error_rings.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 71 KiB

BIN
images/front_side_rgb.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 220 KiB