wipdevice 0.0.1__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (29) hide show
  1. wipdevice-0.0.1/PKG-INFO +19 -0
  2. wipdevice-0.0.1/README.md +51 -0
  3. wipdevice-0.0.1/WIPClient/WIPClient.py +280 -0
  4. wipdevice-0.0.1/WIPClient/WIPClientAbstractModel.py +61 -0
  5. wipdevice-0.0.1/WIPClient/WIPClient_advance.py +301 -0
  6. wipdevice-0.0.1/WIPClient/WIPClient_advance_original.py +363 -0
  7. wipdevice-0.0.1/WIPClient/WIPDevice.py +66 -0
  8. wipdevice-0.0.1/WIPClient/__init__.py +1 -0
  9. wipdevice-0.0.1/WIPClient/interface/HTTPSocketManager.py +323 -0
  10. wipdevice-0.0.1/WIPClient/interface/SocketManager.py +226 -0
  11. wipdevice-0.0.1/WIPClient/interface/SocketManagerV2.py +498 -0
  12. wipdevice-0.0.1/WIPClient/interface/WebSocketManager.py +97 -0
  13. wipdevice-0.0.1/WIPClient/interface/__init__.py +1 -0
  14. wipdevice-0.0.1/WIPClient/protocol/__init__.py +1 -0
  15. wipdevice-0.0.1/WIPClient/protocol/advanced/ConstantVar.py +89 -0
  16. wipdevice-0.0.1/WIPClient/protocol/advanced/JsonDataProtocol.py +87 -0
  17. wipdevice-0.0.1/WIPClient/protocol/advanced/ModelJsonData.py +17 -0
  18. wipdevice-0.0.1/WIPClient/protocol/advanced/__init__.py +1 -0
  19. wipdevice-0.0.1/WIPClient/protocol/advanced/aes256.py +42 -0
  20. wipdevice-0.0.1/WIPClient/protocol/advanced/commonFunction.py +17 -0
  21. wipdevice-0.0.1/pyproject.toml +8 -0
  22. wipdevice-0.0.1/setup.cfg +4 -0
  23. wipdevice-0.0.1/setup.py +23 -0
  24. wipdevice-0.0.1/wipdevice.egg-info/PKG-INFO +19 -0
  25. wipdevice-0.0.1/wipdevice.egg-info/SOURCES.txt +27 -0
  26. wipdevice-0.0.1/wipdevice.egg-info/dependency_links.txt +1 -0
  27. wipdevice-0.0.1/wipdevice.egg-info/not-zip-safe +1 -0
  28. wipdevice-0.0.1/wipdevice.egg-info/requires.txt +1 -0
  29. wipdevice-0.0.1/wipdevice.egg-info/top_level.txt +1 -0
@@ -0,0 +1,19 @@
1
+ Metadata-Version: 2.1
2
+ Name: wipdevice
3
+ Version: 0.0.1
4
+ Summary: Wow IoT Platform API libraries
5
+ Home-page: https://github.com/WOWSYSTEM/WIP-Python
6
+ Author: wowsystem, nobu
7
+ Author-email: contact@wowsystem.co.kr
8
+ License: UNKNOWN
9
+ Keywords: wowsystem,IoT,WIP,IoT Platform,IoT Server,wowsystem,WOW IoT Platform
10
+ Platform: UNKNOWN
11
+ Classifier: Programming Language :: Python :: 3.6
12
+ Classifier: Programming Language :: Python :: 3.7
13
+ Classifier: Programming Language :: Python :: 3.8
14
+ Classifier: Programming Language :: Python :: 3.9
15
+ Classifier: Programming Language :: Python :: 3.10
16
+ Requires-Python: >=3.6
17
+
18
+ UNKNOWN
19
+
@@ -0,0 +1,51 @@
1
+ # WOW IoT Platform Python Library
2
+
3
+ **프로젝트 개요**
4
+ WOW IoT Platform과 연동하여 사용할 수 있는 Python 라이브러리이다.
5
+ 간편하게 IoT Platform과 연동하여, 데이터 전송 및 제어 명령 수신이 가능하다.
6
+
7
+ 디바이스를 연동하기 위해선 IoT Platform에 로그인 후 디바이스를 등록하여야 사용할 수 있다.
8
+
9
+ 해당 라이브러리 개발 시 다양한 테스트 조건에도 문제 없이 Platform에 접속하여 사용할 수 있도록 최선을 다한다.
10
+
11
+
12
+ ## Getting Started
13
+ - Python3.6 버전 이상 파이썬 설치
14
+ - Visual Code 등으로 수정 가능
15
+ - 최종 및 안정화 버전은 PyPI에 업로드 할 수 있으며, 관련 방법은 사내에서 공유되는 자료를 확인
16
+
17
+
18
+ ### Installing
19
+
20
+ WIP Library를 사용하기 위해선 아래의 명령어로 설치 가능하다.
21
+ ```
22
+ pip install wipdevice
23
+ ```
24
+
25
+ 만약 해당 라이브러리의 소스코드 개발 시 아래와 같이 Clone 가능하다.
26
+ ```
27
+ gh repo clone WOWSYSTEM/WIP-Python
28
+ ```
29
+
30
+ pip로 wipdevice를 설치하였다면, dependency로 설치되었겠지만 만약 설치 안한 경우 Crypto를 설치하여야 한다.
31
+ ```
32
+ pip install Crypto
33
+ ```
34
+
35
+ ### Versioning
36
+ * 업데이트 시 반드시 버전 관련 설정 수정할 것
37
+ * 버전 수정안할 시 업데이트 사항이 정상적으로 적용안될 수 있다.
38
+
39
+
40
+ ## Built With / 누구랑 만들었나요?
41
+ * [이승명(nobu)](nobu1015@naver.com, nobu1015@wowsystem.co.kr) - 무엇 무엇을 했어요
42
+
43
+ ## Contributiong / 기여
44
+
45
+ Please read [CONTRIBUTING.md](https://gist.github.com/PurpleBooth/b24679402957c63ec426) for details on our code of conduct, and the process for submitting pull requests to us. / [CONTRIBUTING.md](https://gist.github.com/PurpleBooth/b24679402957c63ec426) 를 읽고 이에 맞추어 pull request 를 해주세요.
46
+
47
+ ## License / 라이센스
48
+ 협의 필요
49
+
50
+ ## Acknowledgments
51
+ * 화이팅
@@ -0,0 +1,280 @@
1
+ import socket
2
+ import time
3
+ import threading
4
+ from .interface import SocketManagerV2
5
+ from .WIPClientAbstractModel import WIPClientAbstractModel
6
+
7
+ class WIPClient(WIPClientAbstractModel, SocketManagerV2.SocketClient):
8
+ # ip : 연결할 서버의 IP
9
+ # port : 연결할 서버의 Port
10
+ # name : 연결할 서버를 구분하기 위한 용도 (ex: iotGateway, AutoVehicle, iotMakers .. 등등)
11
+ def __init__(self, ip="127.0.0.1", port=10008, device_id="device1", device_pw="00000000", isAutoConnect=True, live_receive=True, live_send=False, live_send_interval=1):
12
+ super().__init__(ip, port, "WOW Iot Platform", isAutoConnect=isAutoConnect, live_receive=live_receive)
13
+ self.device_id = str(device_id)
14
+ self.device_pw = str(device_pw)
15
+ self.isCertified = False
16
+
17
+ # 각 데이터가 노드 ID로 구분되기 때문에 WIP Client에서만 사용한다.
18
+ self.live_send = live_send
19
+ self.live_send_run = False
20
+ self.live_send_interval = live_send_interval
21
+ self.socketSendThread = None
22
+ self.sendDataQueues = {}
23
+
24
+ # 서버 자동 접속 쓰레드 호출 시 사용되는 함수 (필요 시 사용자 정의)
25
+ def _connectToServer(self):
26
+ certify_check_time = time.time()
27
+ print("[" + self.log_title + "] Connecting to {0}:{1}...".format(self.ip, self.port))
28
+ while(self.socketConnectThread_Enable):
29
+ try:
30
+ # 한 번 서버에 연결되면 연결이 끊어지기 전까지 더 이상 접속을 시도하지 않도록 함
31
+ if(not self.ser_socket_connect_status):
32
+ self.ser_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
33
+ self.ser_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
34
+ self.ser_socket.connect((self.ip, self.port))
35
+ self.ser_socket_connect_status = True
36
+
37
+ self.ser_socket.send("{0},{1},{2}\n".format(self.device_id, self.device_pw, "S100").encode("utf-8"))
38
+
39
+ # URL로부터 이미지를 읽어들일 경우 (영상 지연 문제로 쓰레드를 별도로 만들어 아래와 같이 비동기로 읽어들임)
40
+ if(self.live_receive):
41
+ self.live_receive_run = True
42
+ self.receiveDataQueue.clear()
43
+ self.socketReceiveThread = threading.Thread(target=self._receiveThread)
44
+ self.socketReceiveThread.setDaemon(True)
45
+ self.socketReceiveThread.start()
46
+
47
+ if(self.live_send):
48
+ self.live_send_run = True
49
+ self.socketSendThread = threading.Thread(target=self._sendThread)
50
+ self.socketSendThread.setDaemon(True)
51
+ self.socketSendThread.start()
52
+
53
+ print("[" + self.log_title + "] Server connection was successful.")
54
+ certify_check_time = time.time() # 인증 체크 시간 초기화
55
+
56
+ # 접속 후 5초 넘게 인증이 완료되지 않았을 경우 재요청
57
+ elif (time.time() - certify_check_time >= 5) and not self.isCertified:
58
+ certify_check_time = time.time()
59
+ print("[" + self.log_title + "] Not certified long time. retry")
60
+ self.ser_socket.send("{0},{1},{2}\n".format(self.device_id, self.device_pw, "S100").encode("utf-8"))
61
+
62
+ except socket.error as e:
63
+ print("[" + self.log_title + "] Connect to server process error " + str(e))
64
+ self.close()
65
+ continue
66
+
67
+ finally:
68
+ time.sleep(1)
69
+
70
+ # 소켓 서버에 IoT 데이터 전송. live_send에 따라 전송 방식이 달라짐
71
+ def sendData(self, values):
72
+ try:
73
+ if(type(values) != list):
74
+ print("[" + self.log_title + "] Invalid data format ({0})".format(value))
75
+ return
76
+ if(type(values[0]) != list):
77
+ values = [values] # to 2d array
78
+
79
+ for value in values:
80
+ if(type(value) != list or len(value) != 3):
81
+ print("[" + self.log_title + "] Invalid data format ({0})".format(value))
82
+ continue
83
+ if(value[1] not in ["CS", "CN", "SS", "SN"]):
84
+ print("[" + self.log_title + "] Invalid data type. ({0})".format(value[1]))
85
+ continue
86
+ value_final = [self.device_id, self.device_pw] + value
87
+ tagData = ','.join(map(str, value_final)) + "\n"
88
+ tagPacket = tagData.encode('utf-8')
89
+
90
+ if(self.live_send):
91
+ if(self.live_send_run and self.socketSendThread.is_alive()):
92
+ self.sendDataQueues[value[0]] = tagPacket
93
+ # else:
94
+ # print("[" + self.log_title + "] {0}:{1} The connection with the socket has been terminated or closed. Data cannot be sent.".format(self.ip, self.port))
95
+ else:
96
+ self.ser_socket.send(tagPacket)
97
+
98
+ except ConnectionResetError:
99
+ self.close()
100
+ print("[" + self.log_title + "] {0}:{1} The connection to the server has been lost.".format(self.ip, self.port))
101
+ pass
102
+ except socket.error as e:
103
+ self.close()
104
+ print("[" + self.log_title + "] {0}:{1} The connection to the server has been lost.".format(self.ip, self.port))
105
+ pass
106
+ finally:
107
+ pass
108
+
109
+ # 소켓 서버에 IoT 데이터 즉시 전송
110
+ def sendDataDirect(self, values):
111
+ try:
112
+ if(type(values) != list):
113
+ print("[" + self.log_title + "] Invalid data format ({0})".format(value))
114
+ return
115
+ if(type(values[0]) != list):
116
+ values = [values] # to 2d array
117
+
118
+ for value in values:
119
+ if(type(value) != list or len(value) != 3):
120
+ print("[" + self.log_title + "] Invalid data format ({0})".format(value))
121
+ continue
122
+ if(value[1] not in ["CS", "CN", "SS", "SN"]):
123
+ print("[" + self.log_title + "] Invalid data type. ({0})".format(value[1]))
124
+ continue
125
+ value_final = [self.device_id, self.device_pw] + value
126
+ tagData = ','.join(map(str, value_final)) + "\n"
127
+ tagPacket = tagData.encode('utf-8')
128
+
129
+ self.ser_socket.send(tagPacket)
130
+
131
+ except ConnectionResetError:
132
+ self.close()
133
+ print("[" + self.log_title + "] {0}:{1} The connection to the server has been lost.".format(self.ip, self.port))
134
+ pass
135
+ except socket.error as e:
136
+ self.close()
137
+ print("[" + self.log_title + "] {0}:{1} The connection to the server has been lost.".format(self.ip, self.port))
138
+ pass
139
+ finally:
140
+ pass
141
+
142
+ def _sendThread(self):
143
+ send_interval_time = 0
144
+ self_break = False
145
+
146
+ while(self.live_send_run):
147
+ try:
148
+ if time.time() - send_interval_time >= self.live_send_interval:
149
+ send_interval_time = time.time()
150
+ # 인증 된 상태인지 확인한다.
151
+ if self.checkCertified() and len(self.sendDataQueues) > 0:
152
+ for key, value in self.sendDataQueues.items():
153
+ self.ser_socket.send(value)
154
+ time.sleep(0.05)
155
+
156
+ except Exception as e:
157
+ self.live_send_run = False
158
+ print("[" + self.log_title + "] Problem processing data in _sendThread. => ", e)
159
+ break
160
+
161
+ finally:
162
+ time.sleep(0.01)
163
+
164
+ # 데이터 자동 수신 쓰레드 호출 시 사용되는 함수 (사용자 정의)
165
+ def _receiveThread(self):
166
+ data = ""
167
+ while(self.live_receive_run):
168
+ try:
169
+ data += self.ser_socket.recv(self.receiveBuffer).decode('utf-8')
170
+
171
+ if data is not None:
172
+ if not (len(data) == 0):
173
+ packets = data.split('\n')
174
+ # 마지막 항목은 제외
175
+ for i in range(len(packets) - 1):
176
+ if len(packets[i]) > 5: # 못해도 5는 넘어야 정상적인 데이터 "A,B,C"
177
+ data_str = packets[i].strip()
178
+ data_list = data_str.split(',')
179
+ if(len(data_list) == 3):
180
+ device_id = data_list[0]
181
+ device_pw = data_list[1]
182
+ status = data_list[2]
183
+ self.isCertified = (device_id == self.device_id and device_pw == self.device_pw and status == "S001")
184
+ if(not self.isCertified):
185
+ print("[" + self.log_title + "] Device not certified. Please check your ID and password again.")
186
+ elif(len(data_list) == 5):
187
+ device_id = data_list[0]
188
+ device_pw = data_list[1]
189
+ tag_id = data_list[2]
190
+ tag_type = data_list[3]
191
+ tag_value = data_list[4]
192
+ self.receiveDataQueue.append([tag_id, tag_type, tag_value])
193
+ else:
194
+ continue
195
+
196
+ # for문을 다 돌았으면, 마지막 하나는 '' 또는 '남은데이터' 이다.
197
+ # data를 packets의 마지막 데이터로 적용하고, 뒤에 데이터 수신 시 쌓을 수 있도록 한다.
198
+ data = packets[-1]
199
+
200
+ else:
201
+ print("[" + self.log_title + "] Disconnect from", str(self.getServerIP()))
202
+ self.close()
203
+ break
204
+
205
+ except ConnectionResetError:
206
+ self.close()
207
+ break
208
+ except socket.timeout as e:
209
+ pass
210
+ except socket.error as e:
211
+ self.close()
212
+ break
213
+ finally:
214
+ time.sleep(0.01)
215
+
216
+ # 소켓 서버로부터 데이터 수신 (사용자 정의)
217
+ def receiveData(self):
218
+ data = ""
219
+ try:
220
+ if(self.live_receive):
221
+ if(self.live_receive_run and self.socketReceiveThread.is_alive()):
222
+ data = self.receiveDataQueue.popleft() if self.receiveDataQueue else None
223
+ else:
224
+ print("The connection with the socket has been terminated. A value of None is returned.")
225
+ data = None
226
+ else:
227
+ data += self.ser_socket.recv(self.receiveBuffer).decode('utf-8')
228
+ if data is not None:
229
+ if not (len(data) == 0):
230
+ packets = data.split('\n')
231
+ # 마지막 항목은 제외
232
+ for i in range(len(packets) - 1):
233
+ if len(packets[i]) > 5: # 못해도 5는 넘어야 정상적인 데이터 "A,B,C"
234
+ data_str = packets[i].strip()
235
+ data_list = data_str.split(',')
236
+ if(len(data_list) == 3):
237
+ device_id = data_list[0]
238
+ device_pw = data_list[1]
239
+ status = data_list[2]
240
+ self.isCertified = (device_id == self.device_id and device_pw == self.device_pw and status == "S001")
241
+ if(not self.isCertified):
242
+ print("[" + self.log_title + "] Device not certified. Please check your ID and password again.")
243
+ elif(len(data_list) == 5):
244
+ device_id = data_list[0]
245
+ device_pw = data_list[1]
246
+ tag_id = data_list[2]
247
+ tag_type = data_list[3]
248
+ tag_value = data_list[4]
249
+ self.receiveDataQueue.append([tag_id, tag_type, tag_value])
250
+ else:
251
+ continue
252
+
253
+ # for문을 다 돌았으면, 마지막 하나는 '' 또는 '남은데이터' 이다.
254
+ # data를 packets의 마지막 데이터로 적용하고, 뒤에 데이터 수신 시 쌓을 수 있도록 한다.
255
+ data = packets[-1]
256
+
257
+ else:
258
+ print("[" + self.log_title + "] Disconnect from", str(self.getServerIP()))
259
+ self.close()
260
+
261
+ return data
262
+
263
+ except ConnectionResetError:
264
+ self.close()
265
+ return None
266
+ except socket.error as e:
267
+ self.close()
268
+ return None
269
+ except Exception as e:
270
+ return None
271
+
272
+ def checkCertified(self):
273
+ return self.isCertified
274
+
275
+ def isExistReceiveData(self):
276
+ return len(self.receiveDataQueue) > 0
277
+
278
+ def waitForConnect(self):
279
+ while(self.socketConnectThread_Enable and not self.checkConnected()):
280
+ time.sleep(0.5)
@@ -0,0 +1,61 @@
1
+ from abc import ABC, ABCMeta, abstractmethod
2
+
3
+ class WIPClientAbstractModel(metaclass=ABCMeta):
4
+ """
5
+ @brief 생성자
6
+ @param ip Server IP
7
+ @param port Server Port
8
+ @param device_id Device ID
9
+ @param device_pw Device PW
10
+ @param isAutoConnect 자동 접속 관련 boolean. True일 경우 연결이 끊길 시 자동으로 접속한다.
11
+ @param live_receive 자동으로 수신관련 처리를 수행할지 여부
12
+ @param live_send 데이터를 자동으로 전송할지 여부
13
+ @param live_send_interval live_send가 True일 경우 전송할 주기
14
+ """
15
+ # @abstractmethod
16
+ # def __init__(self, ip="127.0.0.1", port=10008, device_id="device1", device_pw="00000000", isAutoConnect=True, live_receive=True, live_send=False, live_send_interval=1):
17
+ # print("AbstractModel Initialize")
18
+
19
+ """
20
+ @brief 노드 데이터를 전송하는 메소드
21
+ """
22
+ @abstractmethod
23
+ def sendData(self, values):
24
+ print("AbstractModel sendData")
25
+
26
+ """
27
+ @vbrief
28
+ """
29
+ @abstractmethod
30
+ def sendDataDirect(self, values):
31
+ print("AbstractModel sendDataDirect")
32
+
33
+ """
34
+ @brief 수신받은 데이터를 받는 메소드
35
+ live_receive가 True일 경우 백그라운드에서 수신한 노드 데이터를 리턴한다.
36
+ advanced protocol에서 live_receive가 False일 경우 None 리턴
37
+ """
38
+ @abstractmethod
39
+ def receiveData(self):
40
+ print("AbstractModel receiveData")
41
+
42
+ """
43
+ @brief 인증이 완료되었는지 확인하는 메소드
44
+ """
45
+ @abstractmethod
46
+ def checkCertified(self):
47
+ print("AbstractModel checkCertified")
48
+
49
+ """
50
+ live_receive가 True일 경우 Queue에 받은 데이터가 존재하는지 확인
51
+ """
52
+ @abstractmethod
53
+ def isExistReceiveData(self):
54
+ print("AbstractModel isExistReceiveData")
55
+
56
+ """
57
+ 서버 접속이 완료될 때 까지 대기한다.
58
+ """
59
+ @abstractmethod
60
+ def waitForConnect(self):
61
+ print("AbstractModel waitForConnect")