Commit 7647216c by 이병복

gpio add

parent 7d9b616e
call_no: 012-5553-5575
server_address: 118.46.137.10:20000
max_retries: 3
reconnect_interval: 5
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 (
"io/ioutil"
"net"
"net/http"
"net/url"
"os"
"os/exec"
"strings"
"syscall"
"time"
"golang.org/x/text/encoding/korean"
......@@ -18,14 +22,16 @@ import (
// Config 구조체 정의
type Config struct {
CallNo string `yaml:"call_no"`
ServerAddress string `yaml:"server_address"`
MaxRetries int `yaml:"max_retries"`
ReconnectInterval int `yaml:"reconnect_interval"`
ReadTimeout int `yaml:"read_timeout"`
RestAPIEndpoint string `yaml:"rest_api_endpoint"`
RestAPIGetDevice string `yaml:"rest_api_get_device"`
}
// LogEntry 구조체 정의 (이전과 동일)
// LogEntry 구조체 정의
type LogEntry struct {
Size byte
Type uint8
......@@ -36,7 +42,7 @@ type LogEntry struct {
Device [24]byte
}
// JSONLogEntry 구조체 정의 (이전과 동일)
// JSONLogEntry 구조체 정의
type JSONLogEntry struct {
CallNo string `json:"callNo"`
Type uint8 `json:"type"`
......@@ -47,12 +53,16 @@ type JSONLogEntry struct {
Device string `json:"deviceNm"`
}
// callNo string
// type int
// status string
// zoneNm string
// deviceNm string
// addr string
type DeviceInfo struct {
SeqNo int `json:"seq"`
OrdNo int `json:"ordNo"`
SerialKey string `json:"serial_key"`
CallNo string `json:"call_no"`
DLCIP string `json:"dlc_ip"`
RecIP string `json:"rec_ip"`
// DLCNetmask string `json:"dlc_netmask"`
// DLCGateway string `json:"dlc_gateway"`
}
var config Config
......@@ -71,7 +81,38 @@ func main() {
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 {
if err := runClient(); err != nil {
......@@ -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 {
var conn net.Conn
var err error
......@@ -101,8 +223,11 @@ func runClient() error {
fmt.Println("Connected to server")
setReciverConnectGPIO()
for {
if err := handleConnection(conn); err != nil {
resetReciverConnectGPIO()
return err
}
}
......@@ -110,10 +235,8 @@ func runClient() error {
func handleConnection(conn net.Conn) error {
for {
// 읽기 타임아웃 설정
conn.SetReadDeadline(time.Now().Add(time.Duration(config.ReadTimeout) * time.Second))
// 첫 번째 바이트 (데이터 길이) 읽기
sizeBuf := make([]byte, 1)
_, err := conn.Read(sizeBuf)
if err != nil {
......@@ -122,14 +245,11 @@ func handleConnection(conn net.Conn) error {
size := int(sizeBuf[0])
// size가 0인 경우 처리
if size == 0 {
// fmt.Println("Received packet with size 0, skipping...")
continue
}
fmt.Printf("Received size: %d\n", size)
// 나머지 데이터 읽기
buf := make([]byte, size-1)
_, err = io.ReadFull(conn, buf)
if err != nil {
......@@ -138,7 +258,6 @@ func handleConnection(conn net.Conn) error {
fmt.Printf("Received data: %v\n", buf)
fmt.Printf("Received size: %v\n", len(buf))
// 전체 데이터 (크기 바이트 포함)
fullData := append(sizeBuf, buf...)
logEntry, err := Deserialize(fullData)
......@@ -146,24 +265,20 @@ func handleConnection(conn net.Conn) error {
return fmt.Errorf("deserialization error: %v", err)
}
jsonData, err := convertToJSON(logEntry)
formData, err := convertToFormData(logEntry)
if err != nil {
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)
}
}
}
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)
le := &LogEntry{}
......@@ -172,15 +287,6 @@ func Deserialize(data []byte) (*LogEntry, error) {
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.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]
......@@ -188,80 +294,74 @@ func Deserialize(data []byte) (*LogEntry, error) {
copy(le.Area[:], data[16:40])
copy(le.Device[:], data[40:])
// 로그 출력
fmt.Printf(" Deserialized Packet:\n")
fmt.Printf(" Log_size: %d\n", le.Size)
fmt.Printf(" Log_type: %d\n", le.Type)
fmt.Printf(" Log_datetime: %s\n", le.DateTime)
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(" Deserialized Packet:\n")
// fmt.Printf(" Log_size: %d\n", le.Size)
// fmt.Printf(" Log_type: %d\n", le.Type)
// fmt.Printf(" Log_datetime: %s\n", le.DateTime)
// 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])
areaStr, _ := decodeEUCKR(bytes.TrimRight(le.Area[:], "\x00"))
fmt.Printf(" Log_Area: %s\n", areaStr)
// areaStr, _ := decodeEUCKR(bytes.TrimRight(le.Area[:], "\x00"))
// 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"))
fmt.Printf(" Log_Device: %s\n", deviceStr)
// deviceStr, _ := decodeEUCKR(bytes.TrimRight(le.Device[:], "\x00"))
// 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
}
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"))
if err != nil {
return nil, err
}
fmt.Printf("%d\n", len(le.Device[:]))
device, err := decodeEUCKR(bytes.TrimRight(le.Device[:], "\x00"))
if err != nil {
return nil, err
}
// 로그 타입 변경
// Mapping le.Type to corresponding values
var status string
switch le.Type {
case 1:
le.Type = 6 // 화재
status = "동작"
case 2:
le.Type = 2 // 고장
status = "해제"
case 3:
le.Type = 3 // 설비
status = "해제"
case 4:
le.Type = 4 // 출력
status = "해제"
}
jsonLE := JSONLogEntry{
CallNo: "010-0000-0000",
Type: le.Type,
DateTime: le.DateTime,
Status: func() string {
if le.On == 1 {
return "동작"
}
return "해제"
}(),
Address: fmt.Sprintf("%d%d-%d-%d%d%d-%d",
formData := url.Values{}
formData.Set("callNo", config.CallNo)
formData.Set("type", fmt.Sprintf("%d", le.Type))
formData.Set("dateTime", le.DateTime)
formData.Set("status", status)
formData.Set("addr", fmt.Sprintf("%d%d-%d-%d%d%d-%d",
le.Address[0], le.Address[1], le.Address[2],
le.Address[3], le.Address[4], le.Address[5], le.Address[6]),
Area: area,
Device: device,
}
le.Address[3], le.Address[4], le.Address[5], le.Address[6]))
formData.Set("zoneNm", area)
formData.Set("deviceNm", device)
return json.Marshal(jsonLE)
return formData, nil
}
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 sendToRESTAPI(data []byte) error {
resp, err := http.Post(config.RestAPIEndpoint, "application/json", bytes.NewBuffer(data))
func sendToRESTAPIForm(data url.Values) error {
resp, err := http.PostForm(config.RestAPIEndpoint, data)
if err != nil {
return err
}
......@@ -273,3 +373,37 @@ func sendToRESTAPI(data []byte) error {
return nil
}
func setServerGPIO() error {
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
}
func resetServerGPIO() {
cmd := exec.Command("sh", "-c", "echo 0 > /sys/class/gpio/gpio269/value")
err := cmd.Run()
if err != nil {
fmt.Printf("GPIO 266 리셋 실패: %v", err)
}
}
func setReciverConnectGPIO() error {
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
}
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