티스토리 뷰
반응형
smartthings를 st 공식 api사용하지 않고, api와 같은 형태로 사용하기(api의 문제점 포함)
삼성 가전의 스마트싱스를 개발로 가져오면서 몇가지 불편한점이 존재
-API 사용이 어렵다(가입 인증 WebHook등등)
-공식 API를 사용된 순간 API 서버를 타야하기때문에 반응속도도 느리고, 동기화에도 큰 문제가 생긴다
-스마트싱스 공식앱만이 로컬환경(로컬망)에서 동작하기때문에 속도가 빠르다
이정보를 종합했을때 기본적인 방법으로는 내가 개발한 앱이나 환경에서 빠른 속도로 쓸 방법이 없었다
그래서 고민 끝내 생각해낸 결과
1.윈도우 ST앱의 자동화를 활용
2.해당화면을 늘 유지 할 수있게 만든 후 좌표를 활용한 매크로를 개발
3.해당 좌표와 기능을 DB(또는 메타데이터)로 저장하여 외부 프로토콜을 통해서 Hooking 동작을 하게 처리한다
using bss_st_api.Helpers;
using Launcher_SE.Helpers;
using Rito;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Forms;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Windows.Threading;
using testMouse.Helpers;
using static Rito.HookHelper;
namespace bss_st_api
{
public partial class MainWindow : Window
{
float interval = 5.0f;
System.Drawing.Point iconPT = new System.Drawing.Point(407, 1063);
System.Drawing.Point pt01 = new System.Drawing.Point(407, 1063);
System.Drawing.Point pt02 = new System.Drawing.Point(35, 238);
System.Drawing.Point pt03 = new System.Drawing.Point(31, 240);
System.Drawing.Point pt04 = new System.Drawing.Point(36, 58);
System.Drawing.Color c = System.Drawing.Color.FromArgb(1, 0, 120, 212);
HookHelper hook;
string currentValue;
bool isSave = false;
bool isEdit = false;
bool isServer = false;
string path = @"C:\projects\bss-ex\";
DispatcherTimer timer;
DispatcherTimer processTimer;
public bool UtilHeper { get; private set; }
public MainWindow()
{
InitializeComponent();
Init();
RunPlayMode();
}
private void Instance_PacketReceiveEventHandlerEvent(string code)
{
if (!isEdit)
{
var coordinate = XmlHelper.Instance.Get(code);
if (!coordinate.Equals("fail"))
{
int x = int.Parse(coordinate.Split(':')[0]);
int y = int.Parse(coordinate.Split(':')[1]);
hook.ForceSetCursor(x, y);
hook.ForceLeftClick();
}
}
else
{
}
}
private void Hook_OnRightButtonUp(MouseHookInfo mouseStruct)
{
MousePoint point1 = hook.GetCursorPosition();
currentValue = $"{point1.x}:{point1.y}";
Write(currentValue);
var bounds = Screen.PrimaryScreen.Bounds;
using (Bitmap bitmap = new Bitmap(bounds.Width, bounds.Height))
{
using (Graphics g = Graphics.FromImage(bitmap))
{
g.CopyFromScreen(System.Drawing.Point.Empty, System.Drawing.Point.Empty, bounds.Size);
}
//현재 위치 좌표
System.Drawing.Color color = bitmap.GetPixel(point1.x, point1.y);
Write(color.ToString());
}
if (isSave)
{
MousePoint point = hook.GetCursorPosition();
currentValue = $"{point.x}:{point.y}";
Write(currentValue);
XmlHelper.Instance.Save(txt_index.Text, currentValue);
txt_index.Text = (int.Parse(txt_index.Text) + 1).ToString();
}
}
private void BtnSave_Click(object sender, RoutedEventArgs e)
{
if (isSave)
{
isSave = false;
btnSave.Content = "Save Off";
}
else
{
isSave = true;
btnSave.Content = "Save On";
}
}
public void Init()
{
timer = new DispatcherTimer();
timer.Interval = TimeSpan.FromSeconds(interval);
timer.Tick += Timer_Tick;
processTimer = new DispatcherTimer();
processTimer.Interval = TimeSpan.FromSeconds(3);
processTimer.Tick += ProcessTimer_Tick;
//processTimer.Start();
hook = new HookHelper();
hook.Begin();
hook.OnRightButtonUp += Hook_OnRightButtonUp;
btnSave.Click += BtnSave_Click;
btnServer.Click += BtnServer_Click;
UdpHelper.Instance.Start();
UdpHelper.Instance.PacketReceiveEventHandlerEvent += Instance_PacketReceiveEventHandlerEvent;
}
private void ProcessTimer_Tick(object sender, EventArgs e)
{
processTimer.Stop();
ProcessStartInfo startInfo = new ProcessStartInfo()
{
FileName = "cmd.exe",
Arguments = "/c python main.py", // "/c"는 CMD에게 명령어를 실행하고 종료하라는 의미야
UseShellExecute = false,
RedirectStandardInput = true,
RedirectStandardOutput = true,
CreateNoWindow = false, // CMD 창을 보고 싶으면 이걸 false로 설정
WindowStyle = ProcessWindowStyle.Minimized,
WorkingDirectory = path // CMD가 실행될 경로
};
Process cmdProcess = new Process() { StartInfo = startInfo };
cmdProcess.Start();
//using (StreamWriter sw = cmdProcess.StandardInput)
//{
// if (sw.BaseStream.CanWrite)
// {
// // 이 경로에서 실행하고 싶은 명령어들
// sw.WriteLine("run.bat");
// // 다른 명령어 실행 예
// // sw.WriteLine("dir");
// }
//}
}
private void BtnServer_Click(object sender, RoutedEventArgs e)
{
if (isServer)
{
isServer = false;
timer.Stop();
btnServer.Content = "Server Stop";
}
else
{
isServer = true;
timer.Stop();
timer.Start();
btnServer.Content = "Server Start";
}
}
protected override void OnKeyUp(System.Windows.Input.KeyEventArgs e)
{
if(e.Key == Key.D1)
{
var test = new System.Drawing.Point(413, 1057);
var bounds = Screen.PrimaryScreen.Bounds;
using (Bitmap bitmap = new Bitmap(bounds.Width, bounds.Height))
{
using (Graphics g = Graphics.FromImage(bitmap))
{
g.CopyFromScreen(System.Drawing.Point.Empty, System.Drawing.Point.Empty, bounds.Size);
}
//현재 위치 좌표
System.Drawing.Color color = bitmap.GetPixel(test.X,test.Y);
Write(color.ToString());
}
}
}
private async void Timer_Tick(object sender, EventArgs e)
{
var bounds = Screen.PrimaryScreen.Bounds;
using (Bitmap bitmap = new Bitmap(bounds.Width, bounds.Height))
{
using (Graphics g = Graphics.FromImage(bitmap))
{
g.CopyFromScreen(System.Drawing.Point.Empty, System.Drawing.Point.Empty, bounds.Size);
}
//현재 위치 좌표
System.Drawing.Color color = bitmap.GetPixel(iconPT.X, iconPT.Y);
if (UtilHelper.diff(color, c))
{
Debug.WriteLine("실행중");
}
else
{
isEdit = true;
hook.ForceSetCursor(pt01.X, pt01.Y);
hook.ForceLeftClick();
list.Items.Insert(0, "아이콘 실행");
await Task.Delay(5000);
//hook.ForceSetCursor(pt02.X, pt02.Y);
//hook.ForceLeftClick();
//list.Items.Insert(0, "전체화면 체크");
//await Task.Delay(1000);
hook.ForceSetCursor(pt03.X, pt03.Y);
hook.ForceLeftClick();
list.Items.Insert(0, "자동화 실행");
await Task.Delay(2000);
hook.ForceSetCursor(pt04.X, pt04.Y);
hook.ForceLeftClick();
list.Items.Insert(0, "탭 최소화");
await Task.Delay(2000);
isEdit = false;
}
}
}
public void Write(string text)
{
list.Items.Insert(0, text);
}
public async void RunPlayMode()
{
hook.ForceSetCursor(pt01.X, pt01.Y);
hook.ForceLeftClick();
list.Items.Insert(0, "아이콘 실행");
await Task.Delay(5000);
//hook.ForceSetCursor(pt02.X, pt02.Y);
//hook.ForceLeftClick();
//list.Items.Insert(0, "전체화면 체크");
//await Task.Delay(1000);
hook.ForceSetCursor(pt03.X, pt03.Y);
hook.ForceLeftClick();
list.Items.Insert(0, "자동화 실행");
await Task.Delay(2000);
hook.ForceSetCursor(pt04.X, pt04.Y);
hook.ForceLeftClick();
list.Items.Insert(0, "탭 최소화");
await Task.Delay(2000);
}
}
}
4.비정상적인 팝업이나 예외처리를 추가로 해준다.
import pyautogui
import time
from datetime import datetime # 현재 시간 정보를 가져오기 위해 추가
def find_and_click_center(image_path):
while True: # 무한 루프를 사용하여 계속해서 이미지를 찾음
try:
location = pyautogui.locateOnScreen(image_path, confidence=0.8)
if location is not None:
# 이미지를 찾았다면, 중앙 좌표를 클릭
center = pyautogui.center(location)
pyautogui.click(center)
now = datetime.now() # 현재 시간 가져오기
print(f"{now.strftime('%Y-%m-%d %H:%M:%S')} : {center}")
# 현재 시간을 년-월-일 시:분:초 형식으로 출력
except Exception as e:
pass # 예외가 발생해도 아무 메시지도 출력하지 않음
time.sleep(0.5) # 이미지를 찾은 후 또는 찾지 못했을 때 0.5초 대기
# 이미지 경로 지정
image_path = '1.png' # 실제 이미지 파일 경로로 변경
find_and_click_center(image_path)
5.
반응형
'c#' 카테고리의 다른 글
[autoHotKey/c#] 오토핫키와 c#을 이용한 화면 교체(change Topmost) with udp (0) | 2024.03.06 |
---|---|
adb를 이용한 안드로이드 쉘 사용방법(with source) (0) | 2024.02.06 |
관리자 권한으로 CMD열기(배치파일) (0) | 2023.11.06 |
[c#/wpf/winform] 화면캡쳐하기 (0) | 2022.12.08 |
[c#/wpf] 윈도우 해상도 구하기(멀티 디스플레이 포함) (0) | 2022.12.08 |
댓글
반응형