首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >从Solar Inverter,UDP广播中提取数据?

从Solar Inverter,UDP广播中提取数据?
EN

Stack Overflow用户
提问于 2016-08-07 16:27:00
回答 1查看 317关注 0票数 2

第一个帖子在这里,所以请让我知道如果任何额外的细节将是有用的。

我正在尝试从支持WiFi的太阳能光伏逆变器中提取数据(例如,发电量与时间、今天产生的电量、电池充电水平等)。在playstore中有一个名为kstarmg的android应用程序,它已经做了一些工作,但只有在连接到本地网络时才能工作,因此无法通过互联网访问。我想写一些东西在本地机器(raspberry pi)上运行,记录来自变频器的数据并更新网页。我的第一个想法是使用python。

我已经成功地反编译了android应用程序apk,据我所知,它使用UDP广播与逆变器通信。据我所知,它在端口48899上发送了一些文本"WIFIKIT-214028-READ“。我已经设法通过在树莓派上用nc收听来查看这篇文章。我正在努力解决如何读取逆变器的响应。谁能告诉我如何确定如何从逆变器读取数据?

我在python中尝试了以下操作,但没有得到任何结果:

代码语言:javascript
复制
import socket
import struct

import sys
message = 'WIFIKIT-214028-READ'
multicast_group = ('224.3.29.71', 48899)
# Create the datagram socket                                                                                     sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
# Set a timeout so the socket does not block indefinitely when trying to receive data.
sock.settimeout(20)
# Set the time-to-live for messages to 1 so they do not go past the local network segment.                       ttl = struct.pack('b', 1)
sock.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_TTL, ttl)                                                 
try:
    # Send data to the multicast group
    print >>sys.stderr, 'sending "%s"' % message                                                                     sent = sock.sendto(message, multicast_group)
    # Look for responses from all recipients                                                                         while True:
        print >>sys.stderr, 'waiting to receive'
        try:
            data, server = sock.recvfrom(16)
        except socket.timeout:
            print >>sys.stderr, 'timed out, no more responses'                                                               break
        else:
            print >>sys.stderr, 'received "%s" from %s' % (data, server)
finally:                                                                                                             print >>sys.stderr, 'closing socket'
    sock.close()

android apk中一些看起来相关的代码是:

代码语言:javascript
复制
package com.kstar.common;

import android.util.Log;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
import java.net.SocketTimeoutException;
import java.net.UnknownHostException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

public abstract class UdpBroadcast {
    private static final int BUFFER_SIZE = 100;
    private static final String TAG = "UdpBroadcast";
    private InetAddress inetAddress;
    private DatagramPacket packetToSend;
    private int port;
    private ReceiveData receiveData;
    private DatagramSocket socket;

    /* renamed from: com.kstar.common.UdpBroadcast.1 */
    class C00521 extends Thread {
        C00521() {
        }

        public void run() {
            DatagramPacket packet = new DatagramPacket(new byte[UdpBroadcast.BUFFER_SIZE], UdpBroadcast.BUFFER_SIZE);
            long time = System.currentTimeMillis();
            while (System.currentTimeMillis() - time < 300) {
                try {
                    UdpBroadcast.this.socket.receive(packet);
                } catch (Exception e) {
                }
            }
            try {
                Log.i(UdpBroadcast.TAG, "--UdpBroadcast Send:  ------------>" + new SimpleDateFormat("hh:mm:ss").format(new Date()));
                UdpBroadcast.this.socket.setSoTimeout(1000);
                UdpBroadcast.this.socket.send(UdpBroadcast.this.packetToSend);
            } catch (IOException e2) {
                e2.printStackTrace();
            }
            UdpBroadcast.this.receiveData = new ReceiveData(null);
            Log.i(UdpBroadcast.TAG, "--UdpBroadcast receiveData:  ------------>" + new SimpleDateFormat("hh:mm:ss").format(new Date()));
            UdpBroadcast.this.receiveData.start();
        }
    }

    private class ReceiveData implements Runnable {
        private List<DatagramPacket> packets;
        private boolean stop;
        private Thread thread;

        private ReceiveData() {
            this.thread = new Thread(this);
            this.packets = new ArrayList();
        }

        public void run() {
            this.stop = false;
            while (!this.stop) {
                try {
                    DatagramPacket packetToReceive = new DatagramPacket(new byte[UdpBroadcast.BUFFER_SIZE], UdpBroadcast.BUFFER_SIZE);
                    UdpBroadcast.this.socket.receive(packetToReceive);
                    this.packets.add(packetToReceive);
                } catch (SocketTimeoutException e) {
                } catch (Exception e2) {
                    e2.printStackTrace();
                }
            }
            if (!this.stop) {
                UdpBroadcast.this.onReceived(this.packets);
            }
            this.stop = true;
        }

        void start() {
            this.thread.start();
        }

        void stop() {
            this.stop = true;
        }

        boolean isStoped() {
            return this.stop;
        }
    }

    public abstract void onReceived(List<DatagramPacket> list);

    public void setPort(int port) {
        this.port = port;
    }

    public UdpBroadcast() {
        this.port = Constant.UDP_PORT;
        this.socket = null;
        try {
            this.inetAddress = InetAddress.getByName("255.255.255.255");
        } catch (UnknownHostException e) {
            e.printStackTrace();
        }
    }

    public void open() {
        try {
            if (this.socket == null) {
                this.socket = new DatagramSocket(this.port);
                this.socket.setBroadcast(true);
            }
        } catch (SocketException e) {
            e.printStackTrace();
        }
    }

    public void close() {
        stopReceive();
        if (this.socket != null) {
            this.socket.close();
            this.socket = null;
        }
    }

    public void send(String text) {
        if (this.socket != null && text != null) {
            text = text.trim();
            this.packetToSend = new DatagramPacket(text.getBytes(), text.getBytes().length, this.inetAddress, this.port);
            try {
                this.socket.setSoTimeout(500);
                stopReceive();
                new C00521().start();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    public void stopReceive() {
        if (this.receiveData != null && !this.receiveData.isStoped()) {
            this.receiveData.stop();
        }
    }
}

我正在努力弄清楚下一步该做什么,以便弄清楚发生了什么,所以我会非常感激地接受任何建议。

谢谢

格雷厄姆

EN

回答 1

Stack Overflow用户

发布于 2021-02-07 22:23:13

我设法用PHP来改变逆变器上的定时器,也许这会有帮助。首先,我安装了一个包嗅探器(我使用了HttpCanary)来查找更改计时器的命令。例如,"AA55B07F02390B0701040E00173BFFF1FF7F064E“会将第一个计时器设置为14:00。我使用了以下函数,其中大部分选自here

代码语言:javascript
复制
function send_socket(){
$server = '137.134.128.220';
$port = 13435;
$return="Not OK";
if(!($sock = socket_create(AF_INET, SOCK_DGRAM, 0))){
    $errorcode = socket_last_error();
    $errormsg = socket_strerror($errorcode);
    $return="Couldn't create socket: [$errorcode] $errormsg";
    return $return;
}
$return="Socket created";

$output = hex2bin("AA55B07F02390B0701040E00173BFFF1FF7F064E");//start at 2


//Send the message to the server
if( ! socket_sendto($sock, $output , strlen($output) , 0 , $server , $port)){
    $errorcode = socket_last_error();
    $errormsg = socket_strerror($errorcode);
    $return="Could not send data: [$errorcode] $errormsg";
    return $return;
}

//Now receive reply from server and print it
if(socket_recv ( $sock , $reply , 2045 , MSG_WAITALL ) === FALSE){
    $errorcode = socket_last_error();
    $errormsg = socket_strerror($errorcode);
    $return="Could not receive data: [$errorcode] $errormsg";
    return $return;
}

$return=bin2hex($reply);
echo "Reply: $return";
if ($return=="aa557fb002b9010602f0"){
    $return="Success";
}
return $return;
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/38812321

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档