【发布时间】:2016-08-07 08:27:00
【问题描述】:
第一次在这里发帖,如果有任何额外的细节有用,请告诉我。
我正在尝试从启用 WiFi 的太阳能光伏逆变器中提取数据(例如发电量与时间、今天产生的能量、电池电量等)。 Playstore 中有一个名为 kstarmg 的 android 应用程序,它已经完成了其中的一些工作,但仅在连接到本地网络时才有效,因此无法通过 Internet 访问。我想写一些东西在本地机器(树莓派)上运行,记录来自逆变器的数据并更新网页。我的第一个想法是使用 python。
我已经设法反编译了 android 应用 apk,据我所知,它使用 UDP 广播与逆变器通信。据我所知,它在端口 48899 上发送了一些文本“WIFIKIT-214028-READ”。我通过在树莓派上使用 nc 监听来设法看到这个文本。我正在努力研究如何读取逆变器的响应。谁能指出我如何确定如何从逆变器读取数据?
我在 python 中尝试了以下操作,但没有得到任何回报:
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 中似乎相关的一些行是:
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();
}
}
}
我正在努力弄清楚下一步该怎么做,所以任何建议都会非常感激地接受
谢谢
格雷厄姆
【问题讨论】:
标签: android python udp broadcast