Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

DoorbellDevice works only when device is online #162

Open
jonesMeUp opened this issue Jul 18, 2022 · 1 comment
Open

DoorbellDevice works only when device is online #162

jonesMeUp opened this issue Jul 18, 2022 · 1 comment
Labels
tuya_device Support for specific Tuya Devices

Comments

@jonesMeUp
Copy link

moin,
i didn't make a pull request, because the doorbelldevice works only if the device is online and therefore its useless (at least for me).
but i said i will make a doorbelldevice - so here it is:
DoorbellDevice.zip
its a gift for jasonacox, do with it whatever you want... i give all the rights to you.

# TinyTuya Doorbell Device
# -*- coding: utf-8 -*-
"""
 Python module to interface with Tuya WiFi smart devices

 Author: JonesMeUp
 Tested: LSC-Bell 8S(AKV300_8M)
 Note: Without hack the device can't be used offline. 
       With hack the DoorbellDevice is useless.
        
 For more information see https://github.com/jasonacox/tinytuya

 Local Control Classes
    DoorbellDevice(dev_id, address, local_key=None, dev_type='default')

 Functions
    DoorbellDevice:
        set_basic_indicator(bool):
        set_volume(1-10):
        set_motion_area(x,y,lenX, lenY)
        set_motion_area_switch(bool)
"""

from .core import Device

class DoorbellDevice(Device):
    """
    Represents a Tuya based Video-Doorbell.

    Args:
        dev_id (str): The device id.
        address (str): The network address.
        local_key (str, optional): The encryption key. Defaults to None.
    """
    DPS_2_STATE = {
        "101": "basic_indicator",     # Boolean                                                (status indicator)
        "103": "basic_flip",          # Boolean                                                (flip video vertically)
        "104": "basic_osd",           # Boolean                                                (timestap on video)
        "106": "motion_sensitivity",  # Enum ["0","1","2"]                                     (low, medium, high)
        "108": "basic_nightvision",   # Enum ["0","1","2"]                                     (auto, off, on)
        "109": "sd_storge",           # String ["maxlen":255]                                  (capacity|used|free) e.g: '258048|50176|207872'
        "110": "sd_status",           # Integer ["min":1,"max": 5,"scale":1,"step":1]
        "111": "sd_format",           # Boolean
        "115": "movement_detect_pic", # Raw
        "117": "sd_format_state",     # Integer ["min":-20000,"max":20000,"scale":1,"step":1]
        "134": "motion_switch",       # Boolean                                               (alarm on motion detection)
        "136": "doorbell_active",     # String ["maxlen":255]                                 (doorbell was pressed)
        "150": "record_switch",       # Boolean                                               (false = no recording)
        "151": "record_mode",         # Enum ["1","2"]                                        (1=on event, 2=always)
        "154": "doorbell_pic",        # Raw                                                   (picture of the device)
        "155": "doorbell_ring_exist", # Enum ["0","1"]
        "156": "chime_ring_tune",     # Enum ["1","2","3","4"]
        "157": "chime_ring_volume",   # Integer ["min":0,"max":100,"scale":1,"step":1]        (chime is an extrenal gong [433MhZ])
        "160": "basic_device_volume", # Integer ["min":1,"max": 10,"scale":0,"step":1]
        "165": "chime_settings",      # Enum ["0","2","3"]
        "168": "motion_area_switch",  # Boolean                                               (false = use full area)
        "169": "motion_area",         # String ["maxlen":255]                                 (x, y, xlen, ylen)
        "185": "alarm_message",       # String
    }
    DPS_2_FUNC = {
        "101": "basic_indicator",     # Boolean
        "103": "basic_flip",          # Boolean
        "104": "basic_osd",           # Boolean
        "106": "motion_sensitivity",  # Enum ["0","1","2"]
        "108": "basic_nightvision",   # Enum ["0","1","2"]
        "111": "sd_format",           # Boolean
        "134": "motion_switch",       # Boolean
        "150": "record_switch",       # Boolean
        "151": "record_mode",         # Enum ["1","2"]
        "155": "doorbell_ring_exist", # Enum ["0","1"]
        "156": "chime_ring_tune",     # Enum ["1","2","3","4"]
        "157": "chime_ring_volume",   # Integer ["min":0,"max":100,"scale":1,"step":1]
        "160": "basic_device_volume", # Integer ["min":1,"max": 10,"scale":0,"step":1]
        "165": "chime_settings",      # Enum ["0","2","3"]
        "168": "motion_area_switch",  # Boolean
        "169": "motion_area",         # String ["maxlen":255]
    }

    def __init__(self, dev_id, address, local_key="", dev_type="default"):
        super(DoorbellDevice, self).__init__(dev_id, address, local_key, dev_type)

    def set_basic_indicator(self, val=True, nowait=False):
        """ Set the basic incicator """
        self.set_value(101, bool(val), nowait)

    def set_volume(self, vol=10, nowait=False):
        """ Set the doorbell volume """
        if vol < 3:
            vol = 3 # Nothing to hear below 3
        if vol > 10:
            vol = 10        
        self.set_value(160, int(vol), nowait)

    def set_motion_area(self, x=0,y=0,xlen=50, ylen=100, nowait=False):
        """ set the area of motion detection [%] """
        if x <   0: x = 0
        if y <   0: y = 0
        if x > 100: x = 100
        if y > 100: y = 100
        if xlen <   0: xlen =   0
        if ylen <   0: ylen =   0
        if xlen > 100: xlen = 100
        if ylen > 100: ylen = 100
        if x+xlen >100: 
           x    = 25
           xlen = 75
        if y+ylen >100: 
           y    = 25
           ylen = 75
        data = '{"num":1,"region0":{"x":'+str(x)+',"y":'+str(y)+',"xlen":'+str(xlen)+',"ylen":'+str(ylen)+'}}'
        self.set_value(169, data, nowait)

    def set_motion_area_switch(self, useArea=False, nowait=False):
        """ use the area of motion detection on/off """
        self.set_value(168, bool(useArea), nowait)

if you want to test it put the DoorbellDevice.py into your tinytuya install folder and add
from .DoorbellDevice import DoorbellDevice to your __init__.py
(on my pi the folder for this changes is in /home/pi/.local/lib/python3.9/site-packages/tinytuya/)
and replace the dummy values in d = tinytuya.DoorbellDevice() by your device data in the testfile below

import tinytuya
#tinytuya.set_debug()
"""
Devive LSC-Bell 8S(AKV300_8M)
"""
d = tinytuya.DoorbellDevice('xxxxxxxxxxxxxxxxxxx', '192.168.178.25', 'xxxxxxxxxxxxxxxxx', 'device22')
d.set_version(3.3)
d.set_socketPersistent(True) # Keep socket connection open between commands

d.set_volume(3)
d.set_motion_area(0, 5, 50, 50)
d.set_motion_area_switch(True)

print(" > Begin Monitor Loop <")
while(True):
    # See if any data is available
    data = d.receive()
    print('Data: %r' % data)
    # Send keyalive heartbeat
    print(" > Send Heartbeat Ping < ")
    payload = d.generate_payload(tinytuya.HEART_BEAT)
    d.send(payload)
jasonacox added a commit that referenced this issue Aug 21, 2022
@jasonacox jasonacox added the tuya_device Support for specific Tuya Devices label Aug 21, 2022
@jasonacox
Copy link
Owner

I know the use of this is difficult due to the offline nature, but I have added your good work to our Contrib device list in case someone else discovers a similar device that does work (online) and wants to extend this. Thanks for your contribution, @jonesMeUp !

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
tuya_device Support for specific Tuya Devices
Projects
None yet
Development

No branches or pull requests

2 participants