Commit 7647216c by 이병복

gpio add

parent 7d9b616e
call_no: 012-5553-5575
server_address: 118.46.137.10:20000 server_address: 118.46.137.10:20000
max_retries: 3 max_retries: 3
reconnect_interval: 5 reconnect_interval: 5
read_timeout: 60 read_timeout: 60
rest_api_endpoint: http://localhost:8081/api/data rest_api_endpoint: http://jda.irajas.com/setData/device_kakao_input.php
rest_api_get_device: http://jda.irajas.com/getData/json_device_info.php
...@@ -8,7 +8,11 @@ import ( ...@@ -8,7 +8,11 @@ import (
"io/ioutil" "io/ioutil"
"net" "net"
"net/http" "net/http"
"net/url"
"os" "os"
"os/exec"
"strings"
"syscall"
"time" "time"
"golang.org/x/text/encoding/korean" "golang.org/x/text/encoding/korean"
...@@ -18,14 +22,16 @@ import ( ...@@ -18,14 +22,16 @@ import (
// Config 구조체 정의 // Config 구조체 정의
type Config struct { type Config struct {
CallNo string `yaml:"call_no"`
ServerAddress string `yaml:"server_address"` ServerAddress string `yaml:"server_address"`
MaxRetries int `yaml:"max_retries"` MaxRetries int `yaml:"max_retries"`
ReconnectInterval int `yaml:"reconnect_interval"` ReconnectInterval int `yaml:"reconnect_interval"`
ReadTimeout int `yaml:"read_timeout"` ReadTimeout int `yaml:"read_timeout"`
RestAPIEndpoint string `yaml:"rest_api_endpoint"` RestAPIEndpoint string `yaml:"rest_api_endpoint"`
RestAPIGetDevice string `yaml:"rest_api_get_device"`
} }
// LogEntry 구조체 정의 (이전과 동일) // LogEntry 구조체 정의
type LogEntry struct { type LogEntry struct {
Size byte Size byte
Type uint8 Type uint8
...@@ -36,7 +42,7 @@ type LogEntry struct { ...@@ -36,7 +42,7 @@ type LogEntry struct {
Device [24]byte Device [24]byte
} }
// JSONLogEntry 구조체 정의 (이전과 동일) // JSONLogEntry 구조체 정의
type JSONLogEntry struct { type JSONLogEntry struct {
CallNo string `json:"callNo"` CallNo string `json:"callNo"`
Type uint8 `json:"type"` Type uint8 `json:"type"`
...@@ -47,12 +53,16 @@ type JSONLogEntry struct { ...@@ -47,12 +53,16 @@ type JSONLogEntry struct {
Device string `json:"deviceNm"` Device string `json:"deviceNm"`
} }
// callNo string type DeviceInfo struct {
// type int SeqNo int `json:"seq"`
// status string OrdNo int `json:"ordNo"`
// zoneNm string SerialKey string `json:"serial_key"`
// deviceNm string CallNo string `json:"call_no"`
// addr string DLCIP string `json:"dlc_ip"`
RecIP string `json:"rec_ip"`
// DLCNetmask string `json:"dlc_netmask"`
// DLCGateway string `json:"dlc_gateway"`
}
var config Config var config Config
...@@ -71,7 +81,38 @@ func main() { ...@@ -71,7 +81,38 @@ func main() {
os.Exit(1) os.Exit(1)
} }
fmt.Print(config) fmt.Println(config)
// 장치 정보 가져오기 및 네트워크 설정
maxRetries := 5
for i := 0; i < maxRetries; i++ {
deviceInfo, err := getDeviceInfo(config.CallNo) // config.CallNo는 장치의 고유 번호입니다.
if err != nil {
fmt.Printf("Error getting device info: %v\n", err)
if i == maxRetries-1 {
rebootSystem()
}
time.Sleep(1 * time.Minute)
continue
}
setServerGPIO()
err = setNetworkConfig(deviceInfo)
if err != nil {
fmt.Printf("Error setting network config: %v\n", err)
if i == maxRetries-1 {
rebootSystem()
}
time.Sleep(1 * time.Minute)
continue
}
// 성공적으로 설정되면 루프 종료
config.ServerAddress = deviceInfo.RecIP + ":20000" // 포트 번호는 적절히 변경하세요
break
}
for { for {
if err := runClient(); err != nil { if err := runClient(); err != nil {
...@@ -81,6 +122,87 @@ func main() { ...@@ -81,6 +122,87 @@ func main() {
} }
} }
func getDeviceInfo(callNo string) (*DeviceInfo, error) {
fmt.Print("Getting device info...\n")
fmt.Printf("url:%s\n", config.RestAPIGetDevice)
url := fmt.Sprintf("%s?c=%s", config.RestAPIGetDevice, callNo)
fmt.Println(url)
resp, err := http.Get(url)
if err != nil {
return nil, err
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
return nil, err
}
var deviceInfo DeviceInfo
err = json.Unmarshal(body, &deviceInfo)
if err != nil {
return nil, err
}
return &deviceInfo, nil
}
func setNetworkConfig(info *DeviceInfo) error {
// 이 함수는 실제 시스템 설정을 변경합니다.
// 실제 구현은 운영체제와 환경에 따라 다를 수 있습니다.
fmt.Printf("Setting IP: %s\n", info.DLCIP)
return setIPAddress("eth0", info.DLCIP, "24")
// fmt.Printf("Setting Netmask: %s\n", info.DLCNetmask)
// fmt.Printf("Setting Gateway: %s\n", info.DLCGateway)
// 여기에 실제 네트워크 설정 코드를 추가하세요
// return nil
}
func rebootSystem() {
fmt.Println("Rebooting system...")
// 실제 시스템 재부팅 코드를 여기에 추가하세요
err := syscall.Reboot(syscall.LINUX_REBOOT_CMD_RESTART)
if err != nil {
fmt.Errorf("failed to reboot: %v", err)
}
os.Exit(0)
}
func setIPAddress(interfaceName, ipAddress, netmask string) error {
fmt.Printf("Setting IP address: %s\n", ipAddress)
cmd := exec.Command("ip", "addr", "add", ipAddress+"/"+netmask, "dev", interfaceName)
output, err := cmd.CombinedOutput()
if err != nil {
result := string(output)
if strings.Contains(result, "File exists") {
return nil
}
return fmt.Errorf("failed to set IP address: %v, output: %s", err, output)
}
return setIfconfigUp()
}
func setIfconfigUp() error {
cmd := exec.Command("ip", "link", "set", "eth0", "up")
output, err := cmd.CombinedOutput()
if err != nil {
return fmt.Errorf("failed to set interface up: eth0, err: %v, output: %s", err, output)
}
return nil
}
func runClient() error { func runClient() error {
var conn net.Conn var conn net.Conn
var err error var err error
...@@ -101,8 +223,11 @@ func runClient() error { ...@@ -101,8 +223,11 @@ func runClient() error {
fmt.Println("Connected to server") fmt.Println("Connected to server")
setReciverConnectGPIO()
for { for {
if err := handleConnection(conn); err != nil { if err := handleConnection(conn); err != nil {
resetReciverConnectGPIO()
return err return err
} }
} }
...@@ -110,10 +235,8 @@ func runClient() error { ...@@ -110,10 +235,8 @@ func runClient() error {
func handleConnection(conn net.Conn) error { func handleConnection(conn net.Conn) error {
for { for {
// 읽기 타임아웃 설정
conn.SetReadDeadline(time.Now().Add(time.Duration(config.ReadTimeout) * time.Second)) conn.SetReadDeadline(time.Now().Add(time.Duration(config.ReadTimeout) * time.Second))
// 첫 번째 바이트 (데이터 길이) 읽기
sizeBuf := make([]byte, 1) sizeBuf := make([]byte, 1)
_, err := conn.Read(sizeBuf) _, err := conn.Read(sizeBuf)
if err != nil { if err != nil {
...@@ -122,14 +245,11 @@ func handleConnection(conn net.Conn) error { ...@@ -122,14 +245,11 @@ func handleConnection(conn net.Conn) error {
size := int(sizeBuf[0]) size := int(sizeBuf[0])
// size가 0인 경우 처리
if size == 0 { if size == 0 {
// fmt.Println("Received packet with size 0, skipping...")
continue continue
} }
fmt.Printf("Received size: %d\n", size) fmt.Printf("Received size: %d\n", size)
// 나머지 데이터 읽기
buf := make([]byte, size-1) buf := make([]byte, size-1)
_, err = io.ReadFull(conn, buf) _, err = io.ReadFull(conn, buf)
if err != nil { if err != nil {
...@@ -138,7 +258,6 @@ func handleConnection(conn net.Conn) error { ...@@ -138,7 +258,6 @@ func handleConnection(conn net.Conn) error {
fmt.Printf("Received data: %v\n", buf) fmt.Printf("Received data: %v\n", buf)
fmt.Printf("Received size: %v\n", len(buf)) fmt.Printf("Received size: %v\n", len(buf))
// 전체 데이터 (크기 바이트 포함)
fullData := append(sizeBuf, buf...) fullData := append(sizeBuf, buf...)
logEntry, err := Deserialize(fullData) logEntry, err := Deserialize(fullData)
...@@ -146,24 +265,20 @@ func handleConnection(conn net.Conn) error { ...@@ -146,24 +265,20 @@ func handleConnection(conn net.Conn) error {
return fmt.Errorf("deserialization error: %v", err) return fmt.Errorf("deserialization error: %v", err)
} }
jsonData, err := convertToJSON(logEntry) formData, err := convertToFormData(logEntry)
if err != nil { if err != nil {
return fmt.Errorf("JSON conversion error: %v", err) return fmt.Errorf("JSON conversion error: %v", err)
} }
fmt.Printf("JSON data: %s\n", jsonData) fmt.Printf("formData data: %s\n", formData)
if err := sendToRESTAPI(jsonData); err != nil { if err := sendToRESTAPIForm(formData); err != nil {
return fmt.Errorf("REST API error: %v", err) return fmt.Errorf("REST API error: %v", err)
} }
} }
} }
func Deserialize(data []byte) (*LogEntry, error) { func Deserialize(data []byte) (*LogEntry, error) {
// if len(data) != 64 {
// return nil, fmt.Errorf("invalid data length: expected 64, got %d", len(data))
// }
fmt.Printf("Data: %v\n", data) fmt.Printf("Data: %v\n", data)
le := &LogEntry{} le := &LogEntry{}
...@@ -172,15 +287,6 @@ func Deserialize(data []byte) (*LogEntry, error) { ...@@ -172,15 +287,6 @@ func Deserialize(data []byte) (*LogEntry, error) {
return nil, fmt.Errorf("invalid data length: expected , got %d", le.Size) return nil, fmt.Errorf("invalid data length: expected , got %d", le.Size)
} }
// 수신기에서 넘어오는 타입 값
// 1: 화재
// 2: 고장
// 3: 설비
// 4: 출력
// 5: 운영
// 6: 축적
// 7: 아나로그감지기 예비경보
// 8: 화재복구
le.Type = data[1] le.Type = data[1]
le.DateTime = fmt.Sprintf("%02d-%02d-%02d %02d:%02d:%02d", (int(data[2]) + 2000), data[3], data[4], data[5], data[6], data[7]) le.DateTime = fmt.Sprintf("%02d-%02d-%02d %02d:%02d:%02d", (int(data[2]) + 2000), data[3], data[4], data[5], data[6], data[7])
le.On = data[8] le.On = data[8]
...@@ -188,88 +294,116 @@ func Deserialize(data []byte) (*LogEntry, error) { ...@@ -188,88 +294,116 @@ func Deserialize(data []byte) (*LogEntry, error) {
copy(le.Area[:], data[16:40]) copy(le.Area[:], data[16:40])
copy(le.Device[:], data[40:]) copy(le.Device[:], data[40:])
// 로그 출력 // fmt.Printf(" Deserialized Packet:\n")
fmt.Printf(" Deserialized Packet:\n") // fmt.Printf(" Log_size: %d\n", le.Size)
fmt.Printf(" Log_size: %d\n", le.Size) // fmt.Printf(" Log_type: %d\n", le.Type)
fmt.Printf(" Log_type: %d\n", le.Type) // fmt.Printf(" Log_datetime: %s\n", le.DateTime)
fmt.Printf(" Log_datetime: %s\n", le.DateTime) // fmt.Printf(" Log_On: %d\n", le.On)
fmt.Printf(" Log_On: %d\n", le.On) // fmt.Printf(" Log_Address: %d%d-%d-%d%d%d-%d\n", le.Address[0], le.Address[1], le.Address[2], le.Address[3], le.Address[4], le.Address[5], le.Address[6])
fmt.Printf(" Log_Address: %d%d-%d-%d%d%d-%d\n", le.Address[0], le.Address[1], le.Address[2], le.Address[3], le.Address[4], le.Address[5], le.Address[6])
areaStr, _ := decodeEUCKR(bytes.TrimRight(le.Area[:], "\x00")) // areaStr, _ := decodeEUCKR(bytes.TrimRight(le.Area[:], "\x00"))
fmt.Printf(" Log_Area: %s\n", areaStr) // fmt.Printf(" Log_Area: %s\n", areaStr)
//50 195 254 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 // deviceStr, _ := decodeEUCKR(bytes.TrimRight(le.Device[:], "\x00"))
deviceStr, _ := decodeEUCKR(bytes.TrimRight(le.Device[:], "\x00")) // fmt.Printf(" Log_Device: %s\n", deviceStr)
fmt.Printf(" Log_Device: %s\n", deviceStr)
//191 161 186 241 0 132 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
return le, nil return le, nil
} }
func convertToJSON(le *LogEntry) ([]byte, error) { func decodeEUCKR(b []byte) (string, error) {
decoder := korean.EUCKR.NewDecoder()
result, _, err := transform.Bytes(decoder, b)
if err != nil {
return "", err
}
return string(result), nil
}
func convertToFormData(le *LogEntry) (url.Values, error) {
area, err := decodeEUCKR(bytes.TrimRight(le.Area[:], "\x00")) area, err := decodeEUCKR(bytes.TrimRight(le.Area[:], "\x00"))
if err != nil { if err != nil {
return nil, err return nil, err
} }
fmt.Printf("%d\n", len(le.Device[:]))
device, err := decodeEUCKR(bytes.TrimRight(le.Device[:], "\x00")) device, err := decodeEUCKR(bytes.TrimRight(le.Device[:], "\x00"))
if err != nil { if err != nil {
return nil, err return nil, err
} }
// 로그 타입 변경 // Mapping le.Type to corresponding values
var status string
switch le.Type { switch le.Type {
case 1: case 1:
le.Type = 6 // 화재 le.Type = 6 // 화재
status = "동작"
case 2: case 2:
le.Type = 2 // 고장 le.Type = 2 // 고장
status = "해제"
case 3: case 3:
le.Type = 3 // 설비 le.Type = 3 // 설비
status = "해제"
case 4: case 4:
le.Type = 4 // 출력 le.Type = 4 // 출력
status = "해제"
} }
jsonLE := JSONLogEntry{ formData := url.Values{}
CallNo: "010-0000-0000", formData.Set("callNo", config.CallNo)
Type: le.Type, formData.Set("type", fmt.Sprintf("%d", le.Type))
DateTime: le.DateTime, formData.Set("dateTime", le.DateTime)
Status: func() string { formData.Set("status", status)
if le.On == 1 { formData.Set("addr", fmt.Sprintf("%d%d-%d-%d%d%d-%d",
return "동작" le.Address[0], le.Address[1], le.Address[2],
} le.Address[3], le.Address[4], le.Address[5], le.Address[6]))
return "해제" formData.Set("zoneNm", area)
}(), formData.Set("deviceNm", device)
Address: fmt.Sprintf("%d%d-%d-%d%d%d-%d",
le.Address[0], le.Address[1], le.Address[2], return formData, nil
le.Address[3], le.Address[4], le.Address[5], le.Address[6]), }
Area: area,
Device: device, func sendToRESTAPIForm(data url.Values) error {
resp, err := http.PostForm(config.RestAPIEndpoint, data)
if err != nil {
return err
}
defer resp.Body.Close()
if resp.StatusCode != http.StatusOK {
return fmt.Errorf("unexpected status code: %d", resp.StatusCode)
} }
return json.Marshal(jsonLE) return nil
} }
func decodeEUCKR(b []byte) (string, error) { func setServerGPIO() error {
decoder := korean.EUCKR.NewDecoder() cmd := exec.Command("sh", "-c", "echo 1 > /sys/class/gpio/gpio269/value")
result, _, err := transform.Bytes(decoder, b) err := cmd.Run()
if err != nil { if err != nil {
return "", err fmt.Printf("GPIO 266 설정 실패: %v", err)
} }
return string(result), nil return nil
} }
func sendToRESTAPI(data []byte) error { func resetServerGPIO() {
resp, err := http.Post(config.RestAPIEndpoint, "application/json", bytes.NewBuffer(data)) cmd := exec.Command("sh", "-c", "echo 0 > /sys/class/gpio/gpio269/value")
err := cmd.Run()
if err != nil { if err != nil {
return err fmt.Printf("GPIO 266 리셋 실패: %v", err)
} }
defer resp.Body.Close() }
if resp.StatusCode != http.StatusOK { func setReciverConnectGPIO() error {
return fmt.Errorf("unexpected status code: %d", resp.StatusCode) cmd := exec.Command("sh", "-c", "echo 1 > /sys/class/gpio/gpio269/value")
err := cmd.Run()
if err != nil {
fmt.Printf("GPIO 266 설정 실패: %v", err)
} }
return nil return nil
} }
func resetReciverConnectGPIO() {
cmd := exec.Command("sh", "-c", "echo 0 > /sys/class/gpio/gpio269/value")
err := cmd.Run()
if err != nil {
fmt.Printf("GPIO 266 리셋 실패: %v", err)
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment