YooSee SD-M5 doorbell: 1080p, PoE, RTSP, Onvif, only $66

CCTVCam

Known around here
Joined
Sep 25, 2017
Messages
2,660
Reaction score
3,480
Apologies for not reading all 21 pages. I read as many as I could.

What's the verdict on this camera? Any good?
 

mrxyz

Getting the hang of it
Joined
May 4, 2020
Messages
72
Reaction score
79
Location
Island
Btw, for those interested, writing 0x1 to 0x200f004c will make the doorbell ring. Unfortunately, when you hold the doorbell, the register won't stay 0x1, making it a bit more difficult to hookup an old chime.
 

SecuritySeeker

Pulling my weight
Joined
Oct 5, 2018
Messages
266
Reaction score
156
Location
Netherlands
Ok, so here it goes.
Awesome, thanks for all the detail. Gonna have to try that sometime.

Btw, for those interested, writing 0x1 to 0x200f004c will make the doorbell ring. Unfortunately, when you hold the doorbell, the register won't stay 0x1, making it a bit more difficult to hookup an old chime.
Something else I and I'm sure others would be interested in would be to be able to reliably detect a doorbell press just by listening to the network traffic coming from the doorbell. If you find a way to make that happen please let us know. At the moment the only solution for that to have been shown working is to sniff the 433Mhz wireless signal but that requires extra hardware to do the sniffing. Plus the 433Mhz connection is not always 100% reliable it seems.
 
Last edited:

SecuritySeeker

Pulling my weight
Joined
Oct 5, 2018
Messages
266
Reaction score
156
Location
Netherlands
Would it be possible to do a patch to enable shell access through Ethernet? That way you can mess about with the thing without having to have the serial interface connected all the time.

I'm also wondering if re-compiling the decompiled code is going to result in a functioning binary. On x86 Windows systems that's often not the case, how about on something like this? That way it might be easier to change or add functionality to this thing.
 

mrxyz

Getting the hang of it
Joined
May 4, 2020
Messages
72
Reaction score
79
Location
Island
Would it be possible to do a patch to enable shell access through Ethernet? That way you can mess about with the thing without having to have the serial interface connected all the time.

I'm also wondering if re-compiling the decompiled code is going to result in a functioning binary. On x86 Windows systems that's often not the case, how about on something like this? That way it might be easier to change or add functionality to this thing.
I don't have Hexrays for the ARM CPU series, so I can't do it. Also decompilers are not 100% trustworthy (some exceptions there of course for other languages). In fact, I use Hexrays just to get an idea about what's going on. If I truly want to understand things I prefer to look at the asm.

To answer your question, yes it would be possible to add an ssh daemon to the SD card and add it to the shell script so it starts while booting the device.
 

mrxyz

Getting the hang of it
Joined
May 4, 2020
Messages
72
Reaction score
79
Location
Island
Awesome, thanks for all the detail. Gonna have to try that sometime.



Something else I and I'm sure others would be interested in would be to be able to reliably detect a doorbell press just by listening to the network traffic coming from the doorbell. If you find a way to make that happen please let us know. At the moment the only solution for that to have been shown working is to sniff the 433Mhz wireless signal but that requires extra hardware to do the sniffing. Plus the 433Mhz connection is not always 100% reliable it seems.
Cleanest solution is to write a program that uses mmap() and monitors the memory location. If 0x01 is written there, the program can open a TCP connection to a server on your monitoring system. From there on you can control a cheap USB relay that powers the chime for a certain time interval.
 

mrxyz

Getting the hang of it
Joined
May 4, 2020
Messages
72
Reaction score
79
Location
Island
Cleanest solution is to write a program that uses mmap() and monitors the memory location. If 0x01 is written there, the program can open a TCP connection to a server on your monitoring system. From there on you can control a cheap USB relay that powers the chime for a certain time interval.
Actually I implemented things a bit differently, and took riogrande75 from the domoticz as a base. So what I did was the following:

I wrote a shellscript (see below):

Bash:
#!/bin/sh
tcpsvd -vE 0.0.0.0 21 ftpd -w / &
mount /dev/mmcblk0p1 /mnt/disc1
/mnt/disc1/patched/npc2 &
PID=`/mnt/disc1/busybox pgrep npc2`
/mnt/disc1/busybox mkfifo /tmp/npc.log
/mnt/disc1/notify -i IP -p 31337 -f /tmp/npc.log -m 222222222222 &
/mnt/disc1/reredirect -m /tmp/npc.log $PID
As you can see, I added another version of busybox to my SD card, which I compiled myself and has pgrep enabled. I then grep the pid of the patched npc daemon. I use mkfifo to create a fifo file, so my program (see below) can easily read from it. This way you don't need to store an ever growing log file on your SD card. Then I wrote a program that reads from /tmp/npc.log, and looks for the 222222222222 string. Which is the string that is displayed by the npc daemon when somebody presses the doorbell. If somebody presses the doorbell, a socket connection is opened to IP:31337 and the RINGDINGDING message is sent. Last line of the script redirects the output of the npc process to the fifo file.

Below is the C code. GLHF.
C:
#include <stdio.h>
#include <fcntl.h>
#include <stdlib.h>
#include <unistd.h>
#include <stdint.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <netinet/in.h>
#include "include/iv.h"

#ifndef BUFSIZE
#define BUFSIZE 4096
#endif

#define RING "RINGDINGDING"

#define DIE(x) { fprintf(stderr, "%s", (x)); exit(EXIT_FAILURE); }

struct callback_info
{
    char *message;
    struct iv_fd fifo;
    struct sockaddr_in addr;
};

static void send_ring_cmd(struct callback_info *ci)
{
    int sock;

    if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0)
    {
        perror("Cannot open socket, maybe later...");
        return;
    }

    if (connect(sock, (struct sockaddr *)&(ci->addr), sizeof(struct sockaddr))
        < 0)
    {
        perror("Cannot connect to target, maybe later...");
        return;
    }

    send(sock, RING, strlen(RING), 0);
    close(sock);
}

static void fifo_callback(void *_ci)
{
    int len;
    char buf[BUFSIZE];
    struct callback_info *ci;

    memset(buf, 0x00, sizeof(buf));

    ci = (struct callback_info*)_ci;
    len = read(ci->fifo.fd, buf, sizeof(buf));
   
    if (len <= 0)
    {
        if (len < 0)
        {
            if (errno == EAGAIN)
                return;
            perror("Error reading from fifo: ");
        }
        exit(EXIT_FAILURE);
    }

    if (strstr(buf, ci->message) != NULL)
        send_ring_cmd(ci);
}

static void print_banner()
{
    fprintf(stderr, "Usage: ./notify -i <IP to connect to> -p <port to connect"\
        " to -f <FIFO file to read from> -m <message to search for in log>\n");
}

int main(int argc, char **argv)
{
    int fd;
    int opt;
    char *ip;
    uint16_t port;
    char *fifo_file;
    char *message;
    int tmp;
    struct callback_info ci;

    ip = fifo_file = message = NULL;
    port = 0;  

    while ((opt = getopt(argc, argv, "i:p:f:m:")) != -1)
    {
        switch(opt)
        {
            case 'i':
                ip = optarg;
                break;
            case 'p':
                tmp = atoi(optarg);
                if (tmp < 0 || tmp > UINT16_MAX)
                    DIE("please provide a proper port number\n");
                port = (uint16_t)tmp;
                break;
            case 'f':
                fifo_file = optarg;
                break;
            case 'm':
                message = optarg;
                break;
            default:
                print_banner();
                exit(EXIT_FAILURE);
        }
    }

    if (ip == NULL || fifo_file == NULL || port == 0 || message == NULL)
    {
        print_banner();
        exit(EXIT_FAILURE);
    }

    ci.message = message;
    ci.addr.sin_family = AF_INET;
    ci.addr.sin_port = htons(port);

    if (inet_pton(AF_INET, ip, &ci.addr.sin_addr) < 0)
        DIE("Invalid IP address\n");  

    if ((fd = open(fifo_file, O_RDONLY)) == -1)
        DIE("Cannot open fifo file\n");

    iv_init();
    IV_FD_INIT(&(ci.fifo));
 
    ci.fifo.fd = fd;
    ci.fifo.cookie = (void*)&ci;
    ci.fifo.handler_in = fifo_callback;

    iv_fd_register(&(ci.fifo));
    iv_main();

    iv_deinit();

    return EXIT_SUCCESS;
}
 
Last edited:

Bazzle

n3wb
Joined
Oct 2, 2018
Messages
29
Reaction score
4
Location
australia
41Fa-KHH6GL._AC_.jpg

New Landing 2MP 1080P Wireless WiFi Doorbell POE Intercom Access Control Video Door Phone
YouSee branded.

Setup was easy. Added 'yousee' app to tablet. Registered an account .
Set it up on wifi . 12v power runs thru the wall. Can be hard wired with ethernet and poe if required, many options for power etc.
Can see on app or on my Dahua NVR as an added camera 24/7.
Focus was out a little so I turned the adjustable lens in 1 turn and its ok now. Happy with the purchase.
Notifications come thru on the tablet and on my iphone when I tried it out. Had it running now for about 2 weeks..

Interface with my Dahua NVR is very good. Can see history etc.
Haven't been able to work out if I can record sound 24/7 on nvr.
Further investigation needed.
Picture quality as good as you can get from 2mp :))

Have now connected via ethernet and 12v from an IP cam 4 meters away using a pair of these :)
 

mrxyz

Getting the hang of it
Joined
May 4, 2020
Messages
72
Reaction score
79
Location
Island
I've written also the server side version. It is waiting for a connection on a port and if the RINGDINGDING message is received, it sets a USBrelay to 1 for a certain amount of time. I've attached my chime to the relay and everything works as expected.

At least for me, the doorbell problem is solved.

Btw, code relies on darrylb123/usbrelay I also bought one of those USB relay you see there for around 6$.

C:
#include <stdio.h>
#include <fcntl.h>
#include <stdlib.h>
#include <unistd.h>
#include <stdint.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <iv.h>
#include "usbrelay/libusbrelay.h"

#ifndef BUFSIZE
#define BUFSIZE 4096
#endif

#define RING "RINGDINGDING"
#define CONNECTION_TIMEOUT (10)

#define DIE(x) { fprintf(stderr, "%s", (x)); exit(EXIT_FAILURE); }

struct ring_timeout
{
    struct iv_timer timeout;
};

struct connection
{
    struct iv_fd fd;
    struct iv_timer disconnect_timeout;
};

struct listening_socket
{
    struct iv_fd fd;
};

int ring_time;
char *relay_name;
unsigned char relay_offset;

static void turn_relay_off(void *_rt)
{
    struct ring_timeout *rt;

    rt = (struct ring_timeout*)_rt;

    /set the relay state
    if (operate_relay(relay_name, relay_offset, CMD_OFF, 0) < 0)
        fprintf(stderr, "Error turning the relay off\n");
    
    free(rt);
}

static void connection_handler(void *_conn)
{
    int len;
    char buf[BUF_SIZE];
    struct connection *conn;
    struct ring_timeout *rt;

    conn = (struct connection*)_conn;
    
    if ((len = read(conn->fd.fd, buf, sizeof(buf))) <= 0)
    {
        if (len < 0 && errno == EAGAIN)
            return;
    }

    if (strstr(buf, RING) == NULL)
        goto out;

    if ((rt = malloc(sizeof(*rt))) == NULL)
    {
        fprintf(stderr, "Out of memory, making some space, closing conn\n");
        goto out;
    }   

    /set the relay state
    if (operate_relay(relay_name, relay_offset, CMD_ON, 0) < 0)
    {
        fprintf(stderr, "Error turning the relay on\n");
        goto out;
    }

    IV_TIMER_INIT(&(rt->timeout));
    iv_validate_now();

    rt->timeout.cookie = (void*)rt;
    rt->timeout.handler = turn_relay_off;
    rt->timeout.expires = iv_now;
    rt->timeout.expires.tv_sec += ring_time;

    iv_timer_register(&(rt->timeout));

out:

    iv_timer_unregister(&(conn->disconnect_timeout));
    iv_fd_unregister(&(conn->fd));
    close(conn->fd.fd);
    free(conn);
}

static void client_timeout_expired(void *_conn)
{
    struct connection *conn;

    conn = (struct connection*)_conn;

    iv_fd_unregister(&conn->fd);
    close(conn->fd.fd);
    free(conn);
}

static void listening_socket_handler(void *_ls)
{
    int fd;
    socklen_t addrlen;
    struct connection *conn;
    struct sockaddr_in addr;
    struct listening_socket *ls;

    ls = (struct listening_socket*)_ls;
    addrlen = sizeof(addr);
    fd = accept(ls->fd.fd, (struct sockaddr *)&addr, &addrlen);

    if (fd < 0)
    {
        if (errno == EAGAIN)
            return;
        perror("Error accepting: ");
        exit(EXIT_FAILURE);
    }

    if ((conn = malloc(sizeof(*conn))) == NULL)
    {
        fprintf(stderr, "Out of mem\n");
        close(fd);
        return;
    }

    IV_FD_INIT(&conn->fd);

    conn->fd.fd = fd;
    conn->fd.cookie = (void*)conn;
    conn->fd.handler_in = connection_handler;

    iv_fd_register(&(conn->fd));
    
    /in case of connection timeout
    IV_TIMER_INIT(&conn->disconnect_timeout);
    iv_validate_now();
    
    conn->disconnect_timeout.cookie = (void*)conn;
    conn->disconnect_timeout.handler = client_timeout_expired;
    conn->disconnect_timeout.expires = iv_now;
    conn->disconnect_timeout.expires.tv_sec += CONNECTION_TIMEOUT;
    
    iv_timer_register(&conn->disconnect_timeout);
}

static void print_banner()
{
    fprintf(stderr, "Usage: ./notify -p <port to listen on> -n <port name of"\
        " the relay> -r <ring time, time the relay is open in seconds>"\
        " -o <offset of the relay on your board>\n");
}

int main(int argc, char **argv)
{
    int fd;
    int opt;
    char *ip;
    uint16_t port;
    int tmp;
    struct sockaddr_in addr;
    struct listening_socket ls;

    ip = relay_name = NULL;
    port = 0;   
    relay_offset = 0;

    while ((opt = getopt(argc, argv, "p:n:r:o:")) != -1)
    {
        switch(opt)
        {
            case 'o':
                relay_offset = atoi(optarg);
                break;
            case 'p':
                tmp = atoi(optarg);
                if (tmp < 0 || tmp > UINT16_MAX)
                    DIE("please provide a proper port number\n");
                port = (uint16_t)tmp;
                break;
            case 'n':
                relay_name = optarg;
                break;
            case 'r':
                ring_time = atoi(optarg);
                break;
            default:
                print_banner();
                exit(EXIT_FAILURE);
        }
    }
    
    /need to do this once
    enumerate_relay_boards(getenv("USBID"), 0, 0);

    if (port == 0 || relay_name == NULL)
    {
        print_banner();
        exit(EXIT_FAILURE);
    }

    if ((fd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
    {
        perror("Error creating socket: ");
        exit(EXIT_FAILURE);
    }

    /setup socket stuff
    addr.sin_family = AF_INET;
    addr.sin_addr.s_addr = htonl(INADDR_ANY);
    addr.sin_port = htons(port);

    if (bind(fd, (struct sockaddr*)&addr, sizeof(addr)) < 0)
    {
        perror("Error binding: ");
        exit(EXIT_FAILURE);
    }   

    if (listen(fd, 4) < 0)
    {
        perror("Error listening: ");
        exit(EXIT_FAILURE);
    }

    iv_init();
    IV_FD_INIT(&(ls.fd));
  
    ls.fd.fd = fd;
    ls.fd.cookie = (void*)&ls;
    ls.fd.handler_in = listening_socket_handler;

    iv_fd_register(&(ls.fd));
    iv_main();

    iv_deinit();

    return EXIT_SUCCESS; 
}
 

Wang1

n3wb
Joined
Feb 9, 2020
Messages
1
Reaction score
0
Location
England
Do any other iOS apps work with this? Tried a few but no luck, was hoping to get an app that works with Alexa ( echo show). Also tried monocle ( Alexa skill) but couldn't get it working.
 

sp00025

n3wb
Joined
Jul 26, 2020
Messages
27
Reaction score
13
Location
Madrid
@sp00025 you speak about “it sends a message to MQTT server using its POE connection and then it is possible to trigger any suitable sound device.” how did you configure this sending messages to you MQTT server or how is this working?
Sorry for late answer.
I have a solution for getting a keypress from npc app similar to described here by @mrxyz.
This also involves a full busybox placed on a SD Card and reredirect. Only, I parse the output for a string "keyup = 2", or just keyup.
Furthermore, I compiled a few more tools including mqtt_pub which is doing the job.

If anyone can advice, if the POE used in this doorbell is compatible with the standard 48V 802.3af? All info found is that it is a 24 or 36V max, and no standard type mentioned. If connect it to a POE switch instead of a provided POE splitter with 12V power supply will it burn?
 

vandyman

Getting comfortable
Joined
Jul 24, 2018
Messages
555
Reaction score
1,620
Location
US
Sorry for late answer.
I have a solution for getting a keypress from npc app similar to described here by @mrxyz.
This also involves a full busybox placed on a SD Card and reredirect. Only, I parse the output for a string "keyup = 2", or just keyup.
Furthermore, I compiled a few more tools including mqtt_pub which is doing the job.

If anyone can advice, if the POE used in this doorbell is compatible with the standard 48V 802.3af? All info found is that it is a 24 or 36V max, and no standard type mentioned. If connect it to a POE switch instead of a provided POE splitter with 12V power supply will it burn?
I would not try 48 volts directly. I use my poe switch 48v with a 12 volt inline converter.

Sent from my Pixel 3a XL using Tapatalk
 

SecuritySeeker

Pulling my weight
Joined
Oct 5, 2018
Messages
266
Reaction score
156
Location
Netherlands
If anyone can advice, if the POE used in this doorbell is compatible with the standard 48V 802.3af? All info found is that it is a 24 or 36V max, and no standard type mentioned. If connect it to a POE switch instead of a provided POE splitter with 12V power supply will it burn?
This has all been discussed previously in this thread. The doorbell is not 802.3af compatible, it uses passive PoE. In principle if you connect it to a 802.3af switch it should not get any power at all as it won't get through the negotiation phase. Feeding it with 48V is likely to damage the unit either instantly or in the long run. There's a device from Ubiquity that basically turns an 802.3af powered port into passive which is what I use. All details somewhere in this thread, try searching.
 

sp00025

n3wb
Joined
Jul 26, 2020
Messages
27
Reaction score
13
Location
Madrid
This has all been discussed previously in this thread. The doorbell is not 802.3af compatible, it uses passive PoE. In principle if you connect it to a 802.3af switch it should not get any power at all as it won't get through the negotiation phase. Feeding it with 48V is likely to damage the unit either instantly or in the long run. There's a device from Ubiquity that basically turns an 802.3af powered port into passive which is what I use. All details somewhere in this thread, try searching.
I would not try 48 volts directly. I use my poe switch 48v with a 12 volt inline converter.
Thanks a lot for the info. Indeed, searching this thread more, I found very useful info, for example how to get a 433MHz signal from keypress and its encoding. That definitely needs a try.
Regarding the POE discussion, I realized that it maybe not useful at all in many installation, as powering a doorbell with POE makes impossible to unlock the door... as follows from the user manual.
 

SecuritySeeker

Pulling my weight
Joined
Oct 5, 2018
Messages
266
Reaction score
156
Location
Netherlands
Regarding the POE discussion, I realized that it maybe not useful at all in many installation, as powering a doorbell with POE makes impossible to unlock the door... as follows from the user manual.
Don't remember reading that but in any case I'll be damned if I would ever allow a cloud-connected IoT device to open my front door. Not gonna happen.
 

sp00025

n3wb
Joined
Jul 26, 2020
Messages
27
Reaction score
13
Location
Madrid
Don't remember reading that but in any case I'll be damned if I would ever allow a cloud-connected IoT device to open my front door. Not gonna happen.
You are right about cloud-connection. Even it is easy to block, you loose all the useful services.

So, you are not able to open door remotely, you can only see and talk to a visitor. I found a problem with yoosee app - it misses rings on android, so remote interaction is not an option for me. I have a doorbell on the entrance door, but to the garden not to the house. So sometimes it is useful to open remotely for a postman to leave a parcel inside.

At the moment, the doorbell integrates nicely into Synology using onvif, but it is not working for sending sound other way. It also integrates into a smart home system. But for remote use with mobile, before I can totally cut cloud services, i need intercom and unlock features. What my doorbell currently does -- it sends a snapshot of a visitor to Slack or Telegram on a ring. This notification comes realtime. Further work is needed, but Telegram API looks promising, and recently they start supporting video calling on mobiles. I am now experimenting towards that...
 

mrxyz

Getting the hang of it
Joined
May 4, 2020
Messages
72
Reaction score
79
Location
Island
You are right about cloud-connection. Even it is easy to block, you loose all the useful services.

So, you are not able to open door remotely, you can only see and talk to a visitor. I found a problem with yoosee app - it misses rings on android, so remote interaction is not an option for me. I have a doorbell on the entrance door, but to the garden not to the house. So sometimes it is useful to open remotely for a postman to leave a parcel inside.

At the moment, the doorbell integrates nicely into Synology using onvif, but it is not working for sending sound other way. It also integrates into a smart home system. But for remote use with mobile, before I can totally cut cloud services, i need intercom and unlock features. What my doorbell currently does -- it sends a snapshot of a visitor to Slack or Telegram on a ring. This notification comes realtime. Further work is needed, but Telegram API looks promising, and recently they start supporting video calling on mobiles. I am now experimenting towards that...
I started looking into the Telegram API initially as well. Although it looks interesting, I didn't like it that much personally. Also video was not added yet last time I checked to the libraries that make it much easier to write a telegram bot. Instead, I started looking at the Matrix protocol / Element. Nice thing about the Matrix protocol is that you can build bridges. For example, using Matrix you can build a bridge to IRC or to Telegram. I started working on partly implementing the protocol in C, but I don't have much time and as it is quite some work, don't expect any results in the nearby future / at all.
 

khuchumy

n3wb
Joined
Sep 4, 2020
Messages
8
Reaction score
1
Location
Viet Nam
I not recommend this product because I installed a new one. But the quality video and and audio are very poor. Sound not clearly.
It can connect NVR of Dahua but the FPS not smoothly.
I search another product:
1. DAHUA DB11
2. HIKVISION DS-HD1
anh finally I order Dahua DB11. I will report when got it.
 
Top