VTO Event-Script Anbindung an ioBroker

rettroo

Neuer User
Mitglied seit
1 Jan 2021
Beiträge
19
Punkte für Reaktionen
9
Punkte
3
Hallo zusammen,

seit einigen Wochen bin ich stolzer Besitzer einer VTO4202 mit Kamera, 2 Klingeltaster, NFC Modul und Tastfeld (letzteres ist noch am Weg von China nach Österreich).
Seit heute läuft auch das Script von Riogrande75 fehlerfrei auf meinem Nuc in einer eigenen Debian VM.

Nun möchte ich die Events mit meinem zukünftigen "Hirn" im Smarthome : ioBroker verbinden. Mir fehlt allerdings noch der Ansatz wie ich das angehen soll. Vermutlich mittels http-Request?
Leider habe ich noch keinen Funken Ahnung wie ich das Script dementsprechend bearbeite und ebenso wie ioBroker diese dann empfängt.

Mir wäre also schon geholfen wenn mir jemand den Aufbau des Scriptes erläutert und eventuell Anhand eines Beispieles einen Request beschreibt.
Ebenso einen Ansatz wie ich diese Requests dann in ioBroker empfangen kann.Ich würde mit diesen Aktionen dann in Blockly als Script weiterverarbeiten.

lg,
rettroo
 
Zuletzt bearbeitet:
  • Like
Reaktionen: rani22
Hi,

Das Script hört sich vielversprechend an. Habe ich das richtig verstanden und ich könnte das gleich in ioBroker laufen lassen?
MQQT Server ist läuft da auch! Ist das Script auch kompatibel zur VTO4202?
Ich habe die DahuaVTO.js in ioBroker kopiert und die variablen angepasst. Bekomme aber noch folgenden Fehler im Log, was mache ich Falsch?

Code:
javascript.0    2021-01-24 15:13:22.786    error    (998) at processTicksAndRejections (internal/process/task_queues.js:97:5)
javascript.0    2021-01-24 15:13:22.786    error    (998) at runMicrotasks (<anonymous>)
javascript.0    2021-01-24 15:13:22.786    error    (998) at /opt/iobroker/node_modules/standard-as-callback/built/index.js:19:49
javascript.0    2021-01-24 15:13:22.785    error    (998) at tryCatcher (/opt/iobroker/node_modules/standard-as-callback/built/utils.js:11:23)
javascript.0    2021-01-24 15:13:22.785    error    (998) at /opt/iobroker/node_modules/iobroker.js-controller/lib/states/statesInRedis.js:616:17
javascript.0    2021-01-24 15:13:22.785    error    (998) at /opt/iobroker/node_modules/iobroker.javascript/main.js:1140:17
javascript.0    2021-01-24 15:13:22.785    error    (998) at /opt/iobroker/node_modules/iobroker.javascript/main.js:1559:17
javascript.0    2021-01-24 15:13:22.785    error    (998) at prepareScript (/opt/iobroker/node_modules/iobroker.javascript/main.js:1503:37)
javascript.0    2021-01-24 15:13:22.785    error    (998) at createVM (/opt/iobroker/node_modules/iobroker.javascript/main.js:1280:28)
javascript.0    2021-01-24 15:13:22.785    error    (998) at Object.createScript (vm.js:261:10)
javascript.0    2021-01-24 15:13:22.785    error    (998) at new Script (vm.js:88:7)
javascript.0    2021-01-24 15:13:22.785    error    (998) SyntaxError: Unexpected number
javascript.0    2021-01-24 15:13:22.785    error    (998) ^^
javascript.0    2021-01-24 15:13:22.785    error    (998) this.dahua_host = 10.0.0.11;
javascript.0    2021-01-24 15:13:22.785    error    (998) script.js.Dahua compile failed: at script.js.Dahua:80
javascript.0    2021-01-24 15:13:22.784    info    (998) Start javascript script.js.Dahua
 
Ok, sehr gut.
Du könntest deine Änderungen bzw. eine kleine Anleitung hier posten - falls mal jemand anders Dahua VTO's auch in ioBroker haben möchte.
 
  • Like
Reaktionen: Ld66
Klaro,

- In der Javascript Instanz muss man noch als zusätzliche Instanz "digest-fetch" und "md5" angeben.

1612085318925.png
[Edit Novize: Riesenbild gemäß der Forumsregeln auf Vorschau verkleinert]

- Der Adapter Mqtt - Server muss installiert werden.

- hier das Script für ioBroker.:

Code:
const DigestFetch = require('digest-fetch');
const net = require('net');
const fs = require('fs');
const path = require('path');
const md5 = require('md5');
const mqtt = require('mqtt');

/**
* Class to abstract a dahua doorbell.
*
* On instantiation it automatically connects with the doorbell, logs in and
* subscribes to all events.
*
* When an event is received, it forwards it to the MQTT broker so other systems
* can received those events. This behavior is very generic, users need to listen
* to those MQTT messages and create their own integrations using something like
* node-red for instance.
*
* In time this could be used to create a more user-friendly integration in home assistant,
* but a doorbell is a complicated device and I don't know enough yet to decide how such
* integration would look.
*/

class DahuaVTO {
  deviceType;
  serialNumber;

  /**
   * {Number} requestId
   *
   * Our Request / Response ID that must be in all requests and initated by us.
   * This number auto-increments every time we send a message. Once we've logged in, every
   * response contains the request id of which it's a response of, se it could be used to
   * match responses with requests.
   *
   * I haven't bothered to do so because ,for what I saw, we only care about response order
   * for the initial setup, and we do that on request at a time.
   *
   * If we ever make requests in parallel and we need to associate response to each request,
   * we could use this. For not, it's just an auto-incremental number.
   * */

  requestId = 0;

  // Session ID will be returned after successful login
  /**
   * {Number} sessionId
   *
   * When we try to log in on the doorbell we get a sessionId. From that point on every message
   * we send over the socket needs to have include the sessionID for the doorbell to recognize us.
   */
  sessionId = 0;

  // Will be set after the login, but we initialize to 60s because it's a reasonable default
  /**
   * {Number} keepAliveInterval
   *
   * The number of seconds we have to space our keepAlive messages so the doorbell doesn't close
   * the connection.
   */
  keepAliveInterval = 60;

  /**
   * The ID returned by the `setInterval` call.
   * We keep a reference in case we want to cancel it (maybe in case of failure?)
   */
  _keepAliveTimer;

  /**
   * TCP socket to communicate with the doorbell external unit.
   */
  doorbellSocket;

  /**
   * MQTT client to publish (and maybe receive) messages.
   */
  mqttClient;

  constructor() {
    this.dahua_host = "10.0.0.xx";
    this.dahua_username = "user";
    this.dahua_password = "pass";
    this.mqtt_broker_host = "10.0.0.xx";
    this.mqtt_broker_port = "1883";
    this.mqtt_broker_username = "";
    this.mqtt_broker_password = "";
    this.mqtt_broker_topic_prefix = "DahuaVTO";
    this.digestClient =  new DigestFetch(
      this.dahua_username,
      this.dahua_password
    );

    this.getDeviceDetails().then(({ deviceType, serialNumber }) => {
      this.deviceType = deviceType;
      this.serialNumber = serialNumber;
      this.start();
    });
  }

  /**
   * Starts the app by:
   *    - Opening a TCP socket to the doorbell
   *    - Connecting to the MQTT broker
   *    - Authenticating with the doorbell and subscribing to events.
   */
  start() {
    this.setupDoorbellSocket();
    this.setupMQTT();
    this.initLogin();
  }

  /**
   * Makes a request to the doorbell using digest auth to retrieve the device's information.
   *
   * The information is returned in plain text (not JSON) that we have to parse.
   * For now I think we only care about device type and serial number, which can be
   * used to disambiguate in case we have more than one doorbell.
   */
  async getDeviceDetails() {
    return this.digestClient
      .fetch(
        `http://${this.dahua_host}/cgi-bin/magicBox.cgi?action=getSystemInfo`
      )
      .then((r) => r.text())
      .then((text) => {
        const deviceDetails = text
          .trim()
          .split('\n')
          .reduce((obj, str) => {
            const [key, val] = str.split('=');
            obj[key] = val.trim();
            return obj;
          }, {});
        return deviceDetails;
      });
  }

  /**
   * Saves a snapshot of the doorbells image into the given directory (defaults to /tmp/).
   *
   * By default the file is named with a simple timestamp of the current time (YYYY-MM-DD-H-M-S.jpg)
   *
   */
  saveSnapshot(p = '/tmp/') {
    let now = new Date();
    let dateStr = `${now.getFullYear()}-${
      now.getMonth() + 1
    }-${now.getDate()}-${now.getHours()}-${now.getMinutes()}-${now.getSeconds()}`;
    let destination = path.join(p, `DoorBell_${dateStr}.jpg`);
    this.digestClient
      .fetch(`http://${this.dahua_host}/cgi-bin/snapshot.cgi`)
      .then((r) => {
        return r.buffer();
      })
      .then((buf) => {
        fs.writeFile(destination, buf, 'binary', function (err) {
          if (err) {
            log('Error saving snapshot to disk', err);
          } else {
            log('Snapshot saved');
          }
        });
      });
  }

  /**
   * Creates the TCP socket connection with the doorbell on port 5000.
   *
   * Setups the listener for when we receive data over that socket
   *
   * Also setups other listeners for logging purposes mostly.
   *
   * If something goes wrong, we close everything and try to start over again.
   */
  setupDoorbellSocket() {
    let socket = new net.Socket({ readable: true, writable: true });
    socket.on('end', function () {
      log('Doorbell socket ended');
    });
    socket.on('close', function () {
     log('Doorbell socket closed');
      clearInterval(this._keepAliveTimer);
    });
    socket.on('data', this.receive.bind(this));
    socket.on('error', function (e) {
      log('Doorbell socket error', e);
      this.doorbellSocket.destroy(); // destroy the socket
      this.mqttClient.end(true); // End the mqtt connection right away.
      clearInterval(this._keepAliveTimer); // Stop sending keepalive requests
      this.start(); // Start over again.
    });
    this.doorbellSocket = socket.connect({ port: 5000, host: this.dahua_host });
  }

  /**
   * Configure an initialize the MQTT client.
   *
   * It configures the "Last Will and Testament" (LWT), which is the message send to MQTT
   * if this client gets disconnected in an ungraceful way (e.g. a fatal error).
   *
   * It also adds listeners that right now are only used for logging.
   */
  setupMQTT() {
    this.mqttClient = mqtt.connect({
      host: this.mqtt_broker_host,
      port: this.mqtt_broker_port,
      username: this.mqtt_broker_username,
      password: this.mqtt_broker_password,
      will: {
        topic: `${this.mqtt_broker_topic_prefix}/lwt`,
        payload: 'connected',
        qos: 1,
      },
    });
    this.mqttClient.on('disconnect', function (packet) {
      log('MQTTDisconnect', packet);
    });
    this.mqttClient.on('message', function (topic, message, packet) {
      log('MQTTMessage', { topic, message, packet });
    });
  }

  /**
   * Publishes to MQTT an event with the given name and payload.
   * @param {string} name
   * @param {object} payload
   */
  publishToMQTT(name, payload) {
    let message = JSON.stringify(payload);
    this.mqttClient.publish(
      `${this.mqtt_broker_topic_prefix}/${name}/Event`,
      message
    );
  }

  /**
   * Sends a message with the given data to the doorbell's outside unit using the TCP socket.
   * @param {string} data
   *
   * This is a fairly low level way of communication, so let's dive in.
   *
   * We write binary to the socket, so we have to use buffers.
   *
   * The first 32 bytes of the message are the header.
   * After the header we concat the actual message, which is a JSON string.
   * The header has some bits that are fixed and others that are the length of the message that will
   * come after.
   *
   * I didn't reverse-engineered this myself but it works. Take it as gospel as I did.
   */
  send(data) {
    let json = JSON.stringify(data);
    let buf = Buffer.alloc(32);
    let offset = buf.writeUInt32BE(0x20000000);
    offset = buf.writeUInt32BE(0x44484950, offset);
    offset = buf.writeDoubleBE(0, offset);
    offset = buf.writeUInt32LE(json.length, offset);
    offset = buf.writeUInt32LE(0, offset);
    offset = buf.writeUInt32LE(json.length, offset);
    offset = buf.writeUInt32LE(0, offset);
    buf = Buffer.concat([buf, Buffer.from(json)]);
    this.requestId += 1;
    this.doorbellSocket.write(buf);
  }

  /**
   * Handles received messages from the TCP socket.
   * @param {Buffer} buf
   *
   * The received messages are binary. Once discarded the first 32 bytes (the header),
   * the rest of the message is parsed as as a JSON string.
   *
   * The header contains the length of the received response in bytes 16..20 and the expected
   * length of the response in bytes 24..28 in case we need it, but I haven't found a
   * reason to. Perhaps responses might be sent in several chunks? So far it doesn't seem to be
   * the case.
   *
   * Since we always make requests in the exact same order, we know the first two responses are
   * for the authentication.
   * Subsequent responses can be either events or keepalive responses.
   */
  receive(buf) {
    let str = buf.slice(32).toString();
    let obj = JSON.parse(str);
    if (this.requestId === 1) {
      this.handleFirstLoginPayload(obj);
    } else if (this.requestId === 2) {
      this.handleSecondLoginPayload(obj);
    } else if (obj.method === 'client.notifyEventStream') {
      this.handleEvents(obj.params.eventList);
    } else {
      this.handleGenericPayload(obj);
    }
  }

  /**
   * Sends the initial login request.
   * Note that does not include any password.
   * The response to this request will be negative but that is expected, it will contain the
   * necessary information to login.
   */
  initLogin() {
    this.send({
      id: 10000,
      magic: '0x1234',
      method: 'global.login',
      params: {
        clientType: '',
        ipAddr: '(null)',
        loginType: 'Direct',
        password: '',
        userName: this.dahua_username,
      },
      session: 0,
    });
  }

  /**
   * Handles the response to the initial login request.
   *
   * The response contains a session ID, a realm and a random, which in combination with
   * the username and the password are used to generate an MD5 password that is used
   * for logging in.
   *
   * @param {object} payload
   */
  handleFirstLoginPayload({ session, params: { random, realm } }) {
    this.sessionId = session;
    let randomHash = this.genMD5Hash(random, realm);
    this.send({
      id: 10000, // I assume this ID a high number just because we have to send something.
      magic: '0x1234', // No idea what this is
      method: 'global.login',
      session: this.sessionId,
      params: {
        userName: this.dahua_username,
        password: randomHash,
        clientType: '',
        ipAddr: '(null)',
        loginType: 'Direct',
        authorityType: 'Default',
      },
    });
  }

  /**
   * Handles the response to the second (and last) response to login request.
   *
   * If successful, any subsequent message that includes the session id will be accepted for
   * as long as the socket is not closed.
   *
   * To prevent the socket from closing we send a keepalive message every so often.
   *
   * Also now that we're authenticated we subscribe to all events fired by the doorbell.
   */
  handleSecondLoginPayload(obj) {
    if (obj.result) {
      log('Logging to Dahua Doorbell successful');
      this.keepAliveInterval = obj.params.keepAliveInterval - 5;
      this.attachEventManager();
      this.keepConnectionAlive();
    } else {
      log('Failed to login. Response was: ', obj);
    }
  }

  /**
   * Handles any response not handled by any other method. I believe only keepalive responses
   * will end up here, but added some logging just in case.
   *
   * For now keepalive events are published to MQTT, but I don't see a good reason for that.
   */
  handleGenericPayload(obj) {
    if (
      obj.result === true &&
      obj.params &&
      Object.hasOwnProperty.call(obj.params, 'timeout')
    ) {
      log('Publish KeepAlive event');
      this.publishToMQTT('keepAlive', {
        deviceType: this.deviceType,
        serialNumber: this.serialNumber,
      });
    } else {
      log(
        'handleGenericPayload# Cannot handle received payload',
        obj
      );
    }
  }

  /**
   * Generates a MD5 digest of the username, password, realms and random to send as
   * password when logging in.
   * @param {*} random
   * @param {*} realm
   */
  genMD5Hash(random, realm) {
    const base_credentials = `${this.dahua_username}:${realm}:${this.dahua_password}`;
    const pwddb_hash = md5(base_credentials).toUpperCase();
    const base_pass = `${this.dahua_username}:${random}:${pwddb_hash}`;
    return md5(base_pass).toUpperCase();
  }

  /**
   * Sends the message to subscribe to all dorbell events.
   */
  attachEventManager() {
    this.send({
      id: this.requestId,
      magic: '0x1234',
      method: 'eventManager.attach',
      params: {
        codes: ['All'],
      },
      session: this.sessionId,
    });
  }

  /**
   * Handles the events sent by the doorbell.
   *
   * It just publishes those events along with some information of the device firing them
   * to MQTT
   */
  handleEvents(events) {
    events.forEach((event) => {
      log(`Publish event ${event.Code} to MQTT`);
      this.publishToMQTT(event.Code, {
        Action: event.eventAction,
        Data: event.Data,
        deviceType: this.deviceType,
        serialNumber: this.serialNumber,
      });
    });
  }

  /**
   * Sets up a function to be called periodically to keep the socket open by sending
   * keepalive messages.
   * @param {Number} delay (in seconds)
   */
  keepConnectionAlive(delay) {
    this._keepAliveTimer = setInterval(() => {
      let keepAlivePayload = {
        method: 'global.keepAlive',
        magic: '0x1234',
        params: {
          timeout: delay,
          active: true,
        },
        id: this.requestId,
        session: this.sessionId,
      };

      this.send(keepAlivePayload);
    }, this.keepAliveInterval * 1000);
  }

  /**
   * Remotely triggers the relay 1 (e.g. to open an electric gate).
   *
   * In my VTO 2202 F this also triggers the voice announcing the the door has been opened.
   */
  openDoor() {
    return this.digestClient
      .fetch(
        `http://${this.dahua_host}/cgi-bin/accessControl.cgi?action=openDoor&channel=1&UserID=101&Type=Remote`
      )
      .then((r) => {
        if (r.ok) {
          log('Door relay triggered');
        } else {
          log('Error triggering the door relay', e);
        }
      })
      .catch(e => log('Connection error triggering the door relay'));
  }

  // requestMissedCallsLog() {
  //   this.send({
  //     id: this.requestId,
  //     magic: '0x1234',
  //     method: 'RecordFinder.factory.create',
  //     params: {
  //       name: 'VideoTalkMissedLog',
  //     },
  //     session: this.sessionId,
  //   });
  // }

  // requestMissedCallsLog2(findToken) {
  //   this.send({
  //     id: this.requestId,
  //     magic: '0x1234',
  //     method: 'RecordFinder.startFind',
  //     object: findToken,
  //     params: { condition: null },
  //     session: this.sessionId,
  //   });
  // }

  // requestMissedCallsLog3(findToken) {
  //   this.send({
  //     id: this.requestId,
  //     magic: '0x1234',
  //     method: 'RecordFinder.doFind',
  //     object: findToken,
  //     params: { count: 3 }, // Number of calls to show
  //     session: this.sessionId,
  //   });
  // }
};

exports.default = DahuaVTO;

new DahuaVTO();
 
Zuletzt bearbeitet:
@riogrande75

Ich bekomme desöfteren im Log folgende Warnung, an was könnte das liegen:

Code:
    (1196) script.js.DAHUA.Dahua_Script: Unknown severity level "[object Object]" by log of [handleGenericPayload# Cannot handle received payload]
 
Absolut keine Ahnung. Ich spreche kein js, sorry.
 
Hallo rettroo,

kannst du mir ein paar Infos geben zu dem Script wenn es bei dir läuft?
Im Script sehe ich das ein Snapshot gemacht wird. Wann wird dieser gemacht? Kann leider kein Javascript.
Was für MQTT Events funktionieren denn bei dir?

Gruß Lukas
 
habe auch iobroker am laufen, finde aber keinen mqtt server. Könntest Du bitte eine Schritt für Schritt Anleitung machen? Das wäre super hilfreich.
Danke
 
Hallo,
Du siehst im Script nicht das ein Snapshot gemacht wir sondern das jemand läutet, diese Information parse ich in einen Datenpunkt. Danach löse ich mit Blockly ein kurzes Video aus welches mir auf Telegram gesendet wird.

Ich kann auch kein Javascript...

Hier die möglichen Datenpunkte

1615144595619.png

-- Zusammenführung Doppelpost + Bilder gemäß Boardregeln geschrumpft by stoney

habe auch iobroker am laufen, finde aber keinen mqtt server. Könntest Du bitte eine Schritt für Schritt Anleitung machen? Das wäre super hilfreich.
Danke
1615144705647.png
Adapter installiert?
 
Zuletzt bearbeitet von einem Moderator:
Hallo @riogrande75,

ich habe nun auch endlich das Tastfeld erhalten. Allerdings komme ich nicht ganz klar mit der Konfiguration.
- wo kann ich das/die Passwörter definieren?
- sobald ich zb #123# eingebe bekomme ich zwar eine Aktualisierung in "AccessControl" allerdings mit keinen brauchbaren Daten. Sprich: es ändert sich nur die RecNr. um +1
- Idealerweise sollte ich das eingegebene Passwort erhalten, damit ich diese dann weiter verarbeiten kann. Genauso wie ich es mit den CardIDs der RFIDs mache. Funktioniert großartig.

Nachtrag:
ich habe nun auf die neue SW-Version upgedatet V4.500.0000000.7.R und habe hier auch die Möglichkeit User und Passwörter anzugeben.
Diese Funktionieren auch und schalten das Relais. Leider bekomme ich die User, im Gegensatz zu den CardIDs, nicht per MQTT weitergeleitet....

Im AccessControl kommt an:
{"Data":{"CardNo":"","CardType":null,"LocaleTime":"2021-03-14 11:41:50","Method":0,"Name":"OpenDoor","Password":"","ReaderID":"1","RecNo":26,"SnapURL":"","Status":1,"Type":"Entry","UTC":1615722110,"UserID":"8001"},"deviceType":"VTO4202F","serialNumber":"6K00DDxxxxxxx"}




1615718224339.png
1615718427969.png
 
Zuletzt bearbeitet von einem Moderator:
K.A. - hab kein Tastenfeld. Kann von daher auch schlecht etwas testen.
Öffne die Tür 1x per VTH und dann 1x per Keypad. Logge die Events ($debug=1) und parallel dazu poste mal die HTTP API Abfrage (http://x.x.x.x/cgi-bin/recordFinder.cgi?action=find&name=AccessControlCardRec).
Interessant dazu wäre dann auch noch wie der User bzw. das Passwort in der VTO eingerichtet ist (zum Ermitteln der UserID).
 
Hallo @riogrande75

Ich habe keine VTH. Hier mal der Log vom Script.

Im MQTT kommt an:

{"Data":{"CardNo":"","CardType":null,"LocaleTime":"2021-03-15 10:52:12","Method":0,"Name":"OpenDoor","Password":"","ReaderID":"1","RecNo":29,"SnapURL":"","Status":1,"Type":"Entry","UTC":1615805532,"UserID":"8001"},"deviceType":"VTO4202F","serialNumber":"6K00DD3PAJ220A0"}


Code:
15.3.2021, 10:51:32.989    [info ]: javascript.0 (27482) Stop script script.js.DAHUA.Dahua_Script
15.3.2021, 10:51:32.993    [info ]: javascript.0 (27482) Start javascript script.js.DAHUA.Dahua_Script
15.3.2021, 10:51:32.997    [info ]: javascript.0 (27482) script.js.DAHUA.Dahua_Script: registered 0 subscriptions and 0 schedules
15.3.2021, 10:51:33.075    [info ]: javascript.0 (27482) script.js.DAHUA.Dahua_Script: Logging to Dahua Doorbell successful
15.3.2021, 10:51:33.075    [info ]: javascript.0 (27482) script.js.DAHUA.Dahua_Script: setInterval(ms=55000)
15.3.2021, 10:51:33.087    [warn ]: javascript.0 (27482) script.js.DAHUA.Dahua_Script: Unknown severity level "[object Object]" by log of [handleGenericPayload# Cannot handle received payload]
15.3.2021, 10:51:33.594    [info ]: javascript.0 (27482) script.js.DAHUA.Dahua_Script: Publish event AlarmLocal to MQTT
15.3.2021, 10:51:52.210    [info ]: javascript.0 (27482) script.js.DAHUA.Dahua_Script: Publish event SIPRegisterResult to MQTT
15.3.2021, 10:51:52.211    [info ]: javascript.0 (27482) script.js.DAHUA.Dahua_Script: Publish event SIPRegisterResult to MQTT
15.3.2021, 10:51:52.212    [info ]: javascript.0 (27482) script.js.DAHUA.Dahua_Script: Publish event SIPRegisterResult to MQTT
15.3.2021, 10:51:53.238    [info ]: javascript.0 (27482) script.js.DAHUA.Dahua_Script: Publish event SIPRegisterResult to MQTT
15.3.2021, 10:51:53.239    [info ]: javascript.0 (27482) script.js.DAHUA.Dahua_Script: Publish event SIPRegisterResult to MQTT
15.3.2021, 10:51:53.239    [info ]: javascript.0 (27482) script.js.DAHUA.Dahua_Script: Publish event SIPRegisterResult to MQTT
15.3.2021, 10:52:08.325    [info ]: javascript.0 (27482) script.js.DAHUA.Dahua_Script: Publish event VideoMotion to MQTT
15.3.2021, 10:52:08.326    [info ]: javascript.0 (27482) script.js.DAHUA.Dahua_Script: Publish event VideoMotion to MQTT
15.3.2021, 10:52:08.328    [info ]: javascript.0 (27482) script.js.DAHUA.Dahua_Script: Publish event VideoMotion to MQTT
15.3.2021, 10:52:17.702    [info ]: javascript.0 (27482) script.js.DAHUA.Dahua_Script: Publish event BackKeyLight to MQTT
15.3.2021, 10:52:17.703    [info ]: javascript.0 (27482) script.js.DAHUA.Dahua_Script: Publish event BackKeyLight to MQTT
15.3.2021, 10:52:17.703    [info ]: javascript.0 (27482) script.js.DAHUA.Dahua_Script: Publish event BackKeyLight to MQTT
15.3.2021, 10:52:17.717    [info ]: javascript.0 (27482) script.js.DAHUA.Dahua_Script: Publish event AccessControl to MQTT
15.3.2021, 10:52:17.718    [info ]: javascript.0 (27482) script.js.DAHUA.Dahua_Script: Publish event AccessControl to MQTT
15.3.2021, 10:52:17.718    [info ]: javascript.0 (27482) script.js.DAHUA.Dahua_Script: Publish event AccessControl to MQTT
15.3.2021, 10:52:24.990    [info ]: javascript.0 (27482) script.js.DAHUA.Dahua_Script: Publish event VideoMotion to MQTT
15.3.2021, 10:52:24.990    [info ]: javascript.0 (27482) script.js.DAHUA.Dahua_Script: Publish event VideoMotion to MQTT
15.3.2021, 10:52:24.991    [info ]: javascript.0 (27482) script.js.DAHUA.Dahua_Script: Publish event VideoMotion to MQTT
15.3.2021, 10:52:28.084    [info ]: javascript.0 (27482) script.js.DAHUA.Dahua_Script: Publish KeepAlive event
15.3.2021, 10:52:32.173    [info ]: javascript.0 (27482) script.js.DAHUA.Dahua_Script: Doorbell socket ended
15.3.2021, 10:52:32.173    [info ]: javascript.0 (27482) script.js.DAHUA.Dahua_Script: Doorbell socket closed
15.3.2021, 10:52:50.177    [info ]: javascript.0 (27482) script.js.DAHUA.Dahua_Script: Publish event SIPRegisterResult to MQTT
15.3.2021, 10:52:50.177    [info ]: javascript.0 (27482) script.js.DAHUA.Dahua_Script: Publish event SIPRegisterResult to MQTT
15.3.2021, 10:52:51.199    [info ]: javascript.0 (27482) script.js.DAHUA.Dahua_Script: Publish event SIPRegisterResult to MQTT
15.3.2021, 10:52:51.200    [info ]: javascript.0 (27482) script.js.DAHUA.Dahua_Script: Publish event SIPRegisterResult to MQTT
15.3.2021, 10:52:57.730    [info ]: javascript.0 (27482) script.js.DAHUA.Dahua_Script: Doorbell socket ended
15.3.2021, 10:52:57.731    [info ]: javascript.0 (27482) script.js.DAHUA.Dahua_Script: Doorbell socket closed
15.3.2021, 10:53:23.087    [info ]: javascript.0 (27482) script.js.DAHUA.Dahua_Script: Publish KeepAlive event
15.3.2021, 10:53:48.158    [info ]: javascript.0 (27482) script.js.DAHUA.Dahua_Script: Publish event SIPRegisterResult to MQTT
15.3.2021, 10:53:49.179    [info ]: javascript.0 (27482) script.js.DAHUA.Dahua_Script: Publish event SIPRegisterResult to MQTT

Hier die API Abfrage. Record 27 ist ein RFID und Record 28 eine Tastatureingabe.Ich würde das Passwort (Hier als Test 111111) in MQTT benötigen. Somit bräuchte ich keine User erstellen sondern das eingegebene Passwort in ioBroker weiterverwenden.

Code:
records[27].CardName=Walter Button Blau
records[27].CardNo=f0851xxx
records[27].CreateTime=1615722955
records[27].Door=0
records[27].Method=1
records[27].Password=
records[27].RecNo=28
records[27].Status=1
records[27].URL=
records[27].UserID=1
records[28].CardName=CH
records[28].CardNo=
records[28].CreateTime=1615805532
records[28].Door=0
records[28].Method=0
records[28].Password=111111
records[28].RecNo=29
records[28].Status=1
records[28].URL=
records[28].UserID=8001


Hier noch ein Screenshot für die Userverwaltung der Dahua (erst seit der neuen Version) Ich kann aber nur Username und Pass vergeben. Also keine Räume vergeben.
1615802591102.png
 
Zuletzt bearbeitet:
Wo hast du das PW für den (erfolgreichen) Fingerprint eingetragen? Hier im Bild mit der Userverwaltung oder dort, wo man die PW für das generelle Türöffnen vergibt?
 
Passwörter (Für das Tastenfeld) habe ich wie im Screenshot angegeben. Mit diesem wird dann auch geöffnet.
 
Ok, dann muss dein User mit dem PW 111111 wohl "WG" sein. Welche UserID kommt da, wenn du das PW von User "CH" an der Tastatur verwendest?
 
Es sind 2 User angelegt:

CH mit 111111
WG mit 222222

Codeeingabe #111111#
{"Data":{"CardNo":"","CardType":null,"LocaleTime":"2021-03-15 13:38:12","Method":0,"Name":"OpenDoor","Password":"","ReaderID":"1","RecNo":35,"SnapURL":"","Status":1,"Type":"Entry","UTC":1615815492,"UserID":"8001"},"deviceType":"VTO4202F","serialNumber":"6K00DD3PAJ220A0"}

Codeeingabe #222222#
{"Data":{"CardNo":"","CardType":null,"LocaleTime":"2021-03-15 13:38:57","Method":0,"Name":"OpenDoor","Password":"","ReaderID":"1","RecNo":36,"SnapURL":"","Status":1,"Type":"Entry","UTC":1615815537,"UserID":"8001"},"deviceType":"VTO4202F","serialNumber":"6K00DD3PAJ220A0"}

Hier die Records:
records[34].CardName=CH
records[34].CardNo=
records[34].CreateTime=1615815492
records[34].Door=0
records[34].Method=0
records[34].Password=111111
records[34].RecNo=35
records[34].Status=1
records[34].URL=
records[34].UserID=8001
records[35].CardName=WG
records[35].CardNo=
records[35].CreateTime=1615815537
records[35].Door=0
records[35].Method=0
records[35].Password=222222
records[35].RecNo=36
records[35].Status=1
records[35].URL=
records[35].UserID=8001

Die RecID passt zusammen aber leider wird weder CardNo noch das Password mitgesendet!?
 
Eine Sache könntest du noch probieren: Nimm das PHP Script von mir und baue in Zeile 266 folgendes ein:
Code:
if($debug) var_dump($data);

Danach öffne die Tür nochmal mit dem Code und poste den gesamten Output.
 
puh, die VM mit dem PHP Script habe ich leider schon gelöscht. Das Script wieder in PHP zum laufen zu bringen kostet mich sicher wieder Stunden, oder kennst du einen einfachen, schnellen weg?
Denkst du es macht Sinn beim Sriptersteller "Cibernox" einen Request zu erstellen?
 
Holen Sie sich 3CX - völlig kostenlos!
Verbinden Sie Ihr Team und Ihre Kunden Telefonie Livechat Videokonferenzen

Gehostet oder selbst-verwaltet. Für bis zu 10 Nutzer dauerhaft kostenlos. Keine Kreditkartendetails erforderlich. Ohne Risiko testen.

3CX
Für diese E-Mail-Adresse besteht bereits ein 3CX-Konto. Sie werden zum Kundenportal weitergeleitet, wo Sie sich anmelden oder Ihr Passwort zurücksetzen können, falls Sie dieses vergessen haben.