Merge branch 'release/v0.0.1'
This commit is contained in:
+52
@@ -0,0 +1,52 @@
|
|||||||
|
---
|
||||||
|
kind: pipeline
|
||||||
|
name: default
|
||||||
|
type: docker
|
||||||
|
|
||||||
|
platform:
|
||||||
|
os: linux
|
||||||
|
arch: amd64
|
||||||
|
|
||||||
|
clone:
|
||||||
|
image: reg.int.it2000.com.cn/devops/git
|
||||||
|
tags: true
|
||||||
|
skip_verify: true
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: build
|
||||||
|
image: reg.int.it2000.com.cn/library/golang:1.15.6-buster
|
||||||
|
volumes:
|
||||||
|
- name: deps
|
||||||
|
path: /go
|
||||||
|
environment:
|
||||||
|
GO111MODULE: on
|
||||||
|
GOPROXY: https://goproxy.io
|
||||||
|
commands:
|
||||||
|
- go build -o tele-recv-linux
|
||||||
|
|
||||||
|
- name: release
|
||||||
|
image: plugins/gitea-release
|
||||||
|
volumes:
|
||||||
|
- name: certs
|
||||||
|
path: /etc/ssl/certs
|
||||||
|
settings:
|
||||||
|
api_key: fe1e1a8dd77de7452a3f473984c7ac6fe6c5abaf
|
||||||
|
base_url: https://gitea.int.it2000.com.cn
|
||||||
|
title: 0.0.1
|
||||||
|
files:
|
||||||
|
- tele-recv-linux
|
||||||
|
checksum:
|
||||||
|
- sha256
|
||||||
|
when:
|
||||||
|
event: tag
|
||||||
|
|
||||||
|
volumes:
|
||||||
|
- name: deps
|
||||||
|
host:
|
||||||
|
path: /opt/go
|
||||||
|
- name: certs
|
||||||
|
host:
|
||||||
|
path: /etc/ssl/certs
|
||||||
|
- name: docker
|
||||||
|
host:
|
||||||
|
path: /var/run/docker.sock
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
tty*
|
||||||
|
telegram.db
|
||||||
|
.idea
|
||||||
Generated
-8
@@ -1,8 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<project version="4">
|
|
||||||
<component name="ProjectModuleManager">
|
|
||||||
<modules>
|
|
||||||
<module fileurl="file://$PROJECT_DIR$/.idea/tele-recv.iml" filepath="$PROJECT_DIR$/.idea/tele-recv.iml" />
|
|
||||||
</modules>
|
|
||||||
</component>
|
|
||||||
</project>
|
|
||||||
Generated
-8
@@ -1,8 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<module type="WEB_MODULE" version="4">
|
|
||||||
<component name="NewModuleRootManager">
|
|
||||||
<content url="file://$MODULE_DIR$" />
|
|
||||||
<orderEntry type="inheritedJdk" />
|
|
||||||
<orderEntry type="sourceFolder" forTests="false" />
|
|
||||||
</component>
|
|
||||||
</module>
|
|
||||||
Generated
-44
@@ -1,44 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<project version="4">
|
|
||||||
<component name="ChangeListManager">
|
|
||||||
<list default="true" id="ab419b68-984b-4661-bb9a-26bcba1547b3" name="Default Changelist" comment="" />
|
|
||||||
<option name="SHOW_DIALOG" value="false" />
|
|
||||||
<option name="HIGHLIGHT_CONFLICTS" value="true" />
|
|
||||||
<option name="HIGHLIGHT_NON_ACTIVE_CHANGELIST" value="false" />
|
|
||||||
<option name="LAST_RESOLUTION" value="IGNORE" />
|
|
||||||
</component>
|
|
||||||
<component name="GOROOT" url="file:///usr/local/Cellar/go/1.15.5/libexec" />
|
|
||||||
<component name="ProjectId" id="1lm7nLrR9364W3kc4Ropplb4iwV" />
|
|
||||||
<component name="ProjectViewState">
|
|
||||||
<option name="hideEmptyMiddlePackages" value="true" />
|
|
||||||
<option name="showLibraryContents" value="true" />
|
|
||||||
</component>
|
|
||||||
<component name="PropertiesComponent">
|
|
||||||
<property name="RunOnceActivity.OpenProjectViewOnStart" value="true" />
|
|
||||||
<property name="RunOnceActivity.ShowReadmeOnStart" value="true" />
|
|
||||||
<property name="WebServerToolWindowFactoryState" value="false" />
|
|
||||||
<property name="go.import.settings.migrated" value="true" />
|
|
||||||
<property name="go.sdk.automatically.set" value="true" />
|
|
||||||
<property name="go.tried.to.enable.integration.vgo.integrator" value="true" />
|
|
||||||
<property name="last_opened_file_path" value="$PROJECT_DIR$" />
|
|
||||||
<property name="node.js.detected.package.eslint" value="true" />
|
|
||||||
<property name="node.js.detected.package.tslint" value="true" />
|
|
||||||
<property name="node.js.path.for.package.eslint" value="project" />
|
|
||||||
<property name="node.js.path.for.package.tslint" value="project" />
|
|
||||||
<property name="node.js.selected.package.eslint" value="(autodetect)" />
|
|
||||||
<property name="node.js.selected.package.tslint" value="(autodetect)" />
|
|
||||||
<property name="settings.editor.selected.configurable" value="terminal" />
|
|
||||||
</component>
|
|
||||||
<component name="SpellCheckerSettings" RuntimeDictionaries="0" Folders="0" CustomDictionaries="0" DefaultDictionary="application-level" UseSingleDictionary="true" transferred="true" />
|
|
||||||
<component name="TypeScriptGeneratedFilesManager">
|
|
||||||
<option name="version" value="3" />
|
|
||||||
</component>
|
|
||||||
<component name="VgoProject">
|
|
||||||
<integration-enabled>true</integration-enabled>
|
|
||||||
<environment>
|
|
||||||
<map>
|
|
||||||
<entry key="GOPROXY" value="https://goproxy.io" />
|
|
||||||
</map>
|
|
||||||
</environment>
|
|
||||||
</component>
|
|
||||||
</project>
|
|
||||||
-55
@@ -1,55 +0,0 @@
|
|||||||
/*
|
|
||||||
Copyright © 2020 NAME HERE <EMAIL ADDRESS>
|
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
you may not use this file except in compliance with the License.
|
|
||||||
You may obtain a copy of the License at
|
|
||||||
|
|
||||||
http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
|
|
||||||
Unless required by applicable law or agreed to in writing, software
|
|
||||||
distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
See the License for the specific language governing permissions and
|
|
||||||
limitations under the License.
|
|
||||||
*/
|
|
||||||
package cmd
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
|
|
||||||
"github.com/spf13/cobra"
|
|
||||||
)
|
|
||||||
|
|
||||||
// readCmd represents the read command
|
|
||||||
var readCmd = &cobra.Command{
|
|
||||||
Use: "read",
|
|
||||||
Short: "A brief description of your command",
|
|
||||||
Long: `A longer description that spans multiple lines and likely contains examples
|
|
||||||
and usage of using your command. For example:
|
|
||||||
|
|
||||||
Cobra is a CLI library for Go that empowers applications.
|
|
||||||
This application is a tool to generate the needed files
|
|
||||||
to quickly create a Cobra application.`,
|
|
||||||
Run: func(cmd *cobra.Command, args []string) {
|
|
||||||
fmt.Println("read called")
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
func init() {
|
|
||||||
rootCmd.AddCommand(readCmd)
|
|
||||||
|
|
||||||
// Here you will define your flags and configuration settings.
|
|
||||||
|
|
||||||
// Cobra supports Persistent Flags which will work for this command
|
|
||||||
// and all subcommands, e.g.:
|
|
||||||
// readCmd.PersistentFlags().String("foo", "", "A help for foo")
|
|
||||||
|
|
||||||
// Cobra supports local flags which will only run when this command
|
|
||||||
// is called directly, e.g.:
|
|
||||||
// readCmd.Flags().BoolP("toggle", "t", false, "Help message for toggle")
|
|
||||||
}
|
|
||||||
|
|
||||||
func read() {
|
|
||||||
|
|
||||||
}
|
|
||||||
+10
-1
@@ -28,6 +28,12 @@ var (
|
|||||||
device string
|
device string
|
||||||
baudrate int
|
baudrate int
|
||||||
bytesize byte
|
bytesize byte
|
||||||
|
lograw bool
|
||||||
|
|
||||||
|
dbFile string
|
||||||
|
dbInit bool
|
||||||
|
|
||||||
|
socketAddress string
|
||||||
|
|
||||||
// rootCmd represents the base command when called without any subcommands
|
// rootCmd represents the base command when called without any subcommands
|
||||||
rootCmd = &cobra.Command{
|
rootCmd = &cobra.Command{
|
||||||
@@ -83,12 +89,15 @@ func initConfig() {
|
|||||||
|
|
||||||
viper.AutomaticEnv() // read in environment variables that match
|
viper.AutomaticEnv() // read in environment variables that match
|
||||||
|
|
||||||
|
|
||||||
// If a config file is found, read it in.
|
// If a config file is found, read it in.
|
||||||
if err := viper.ReadInConfig(); err == nil {
|
if err := viper.ReadInConfig(); err == nil {
|
||||||
fmt.Println("Using config file:", viper.ConfigFileUsed())
|
fmt.Println("Using config file:", viper.ConfigFileUsed())
|
||||||
device = viper.GetString("serial.device")
|
device = viper.GetString("serial.device")
|
||||||
baudrate = viper.GetInt("serial.baudrate")
|
baudrate = viper.GetInt("serial.baudrate")
|
||||||
bytesize = byte(viper.GetInt("serial.bytesize"))
|
bytesize = byte(viper.GetInt("serial.bytesize"))
|
||||||
|
lograw = viper.GetBool("serial.lograw")
|
||||||
|
dbFile = viper.GetString("sqlite.file")
|
||||||
|
dbInit = viper.GetBool("sqlite.init")
|
||||||
|
socketAddress = viper.GetString("socket.address")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+106
@@ -0,0 +1,106 @@
|
|||||||
|
/*
|
||||||
|
Copyright © 2020 NAME HERE <EMAIL ADDRESS>
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
*/
|
||||||
|
package cmd
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"log"
|
||||||
|
"os"
|
||||||
|
"os/signal"
|
||||||
|
"syscall"
|
||||||
|
|
||||||
|
"it2000.com.cn/tele-recv/utils"
|
||||||
|
|
||||||
|
"github.com/spf13/cobra"
|
||||||
|
)
|
||||||
|
|
||||||
|
// startCmd represents the start command
|
||||||
|
var startCmd = &cobra.Command{
|
||||||
|
Use: "start",
|
||||||
|
Short: "start telegram receive service",
|
||||||
|
Long: `open serial port
|
||||||
|
start a tcp server for processing`,
|
||||||
|
Run: func(cmd *cobra.Command, args []string) {
|
||||||
|
start()
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
rootCmd.AddCommand(startCmd)
|
||||||
|
|
||||||
|
// Here you will define your flags and configuration settings.
|
||||||
|
|
||||||
|
// Cobra supports Persistent Flags which will work for this command
|
||||||
|
// and all subcommands, e.g.:
|
||||||
|
// startCmd.PersistentFlags().String("foo", "", "A help for foo")
|
||||||
|
|
||||||
|
// Cobra supports local flags which will only run when this command
|
||||||
|
// is called directly, e.g.:
|
||||||
|
// startCmd.Flags().BoolP("toggle", "t", false, "Help message for toggle")
|
||||||
|
}
|
||||||
|
|
||||||
|
func start() {
|
||||||
|
// Go signal notification works by sending `os.Signal`
|
||||||
|
// values on a channel. We'll create a channel to
|
||||||
|
// receive these notifications (we'll also make one to
|
||||||
|
// notify us when the program can exit).
|
||||||
|
sigs := make(chan os.Signal, 1)
|
||||||
|
done := make(chan bool, 1)
|
||||||
|
|
||||||
|
// `signal.Notify` registers the given channel to
|
||||||
|
// receive notifications of the specified signals.
|
||||||
|
signal.Notify(sigs, syscall.SIGINT, syscall.SIGTERM)
|
||||||
|
utils.ServerRunning = true
|
||||||
|
|
||||||
|
// This goroutine executes a blocking receive for
|
||||||
|
// signals. When it gets one it'll print it out
|
||||||
|
// and then notify the program that it can finish.
|
||||||
|
go func() {
|
||||||
|
sig := <-sigs
|
||||||
|
fmt.Println()
|
||||||
|
fmt.Println(sig)
|
||||||
|
utils.ServerRunning = false
|
||||||
|
utils.StopSocketServer()
|
||||||
|
done <- true
|
||||||
|
}()
|
||||||
|
|
||||||
|
// The program will wait here until it gets the
|
||||||
|
// expected signal (as indicated by the goroutine
|
||||||
|
// above sending a value on `done`) and then exit.
|
||||||
|
fmt.Println("awaiting signal")
|
||||||
|
_ = utils.InitDb(dbFile, dbInit)
|
||||||
|
go utils.Listen(socketAddress)
|
||||||
|
for utils.ServerRunning {
|
||||||
|
if !utils.IsPortOpen() {
|
||||||
|
log.Println("try to open port")
|
||||||
|
err := utils.OpenPort(device, baudrate, bytesize)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal("error in open serial port ", err)
|
||||||
|
}
|
||||||
|
log.Println("starting read")
|
||||||
|
}
|
||||||
|
buffer, count := utils.ReadPort()
|
||||||
|
if count > 0 {
|
||||||
|
if lograw {
|
||||||
|
log.Print(string(buffer))
|
||||||
|
}
|
||||||
|
utils.Append(buffer)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
<-done
|
||||||
|
fmt.Println("exiting")
|
||||||
|
|
||||||
|
}
|
||||||
+17
-16
@@ -16,32 +16,33 @@ limitations under the License.
|
|||||||
package cmd
|
package cmd
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
"github.com/tarm/serial"
|
"it2000.com.cn/tele-recv/utils"
|
||||||
"os"
|
"log"
|
||||||
)
|
)
|
||||||
|
|
||||||
// testCmd represents the test command
|
// testCmd represents the test command
|
||||||
var testCmd = &cobra.Command{
|
var testCmd = &cobra.Command{
|
||||||
Use: "test",
|
Use: "test",
|
||||||
Short: "Test Config",
|
Short: "Test running environment",
|
||||||
Long: `Test config file.
|
Long: `loading config file
|
||||||
Test serial port`,
|
Test serial port
|
||||||
|
Test load sqlite database and init table`,
|
||||||
Run: func(cmd *cobra.Command, args []string) {
|
Run: func(cmd *cobra.Command, args []string) {
|
||||||
fmt.Println("test called")
|
test()
|
||||||
fmt.Println("device :",device)
|
|
||||||
c := &serial.Config{Name: device, Baud: baudrate, Size: bytesize}
|
|
||||||
s, err := serial.OpenPort(c)
|
|
||||||
if err != nil {
|
|
||||||
fmt.Println(err)
|
|
||||||
os.Exit(1)
|
|
||||||
}
|
|
||||||
fmt.Println(c , "opened")
|
|
||||||
_ = s.Close()
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func test() {
|
||||||
|
log.Println("Testing environment")
|
||||||
|
_ = utils.OpenPort(device, baudrate, bytesize)
|
||||||
|
|
||||||
|
err := utils.InitDb(dbFile, dbInit)
|
||||||
|
if err != nil {
|
||||||
|
println("create database error ", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
rootCmd.AddCommand(testCmd)
|
rootCmd.AddCommand(testCmd)
|
||||||
|
|
||||||
|
|||||||
@@ -1,41 +0,0 @@
|
|||||||
package database
|
|
||||||
|
|
||||||
import (
|
|
||||||
"database/sql"
|
|
||||||
"log"
|
|
||||||
"os"
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
|
||||||
DbDriver = "sqlite3"
|
|
||||||
TableCreate =`'''
|
|
||||||
create table IF NOT EXISTS telegram (
|
|
||||||
[tele_id] INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
||||||
[tele_recv_time] TIMESTAMP NOT NULL DEFAULT (datetime('now', 'localtime')),
|
|
||||||
[tele_processed] int(1) NOT NULL DEFAULT 0,
|
|
||||||
[tele_text] TEXT NOT NULL
|
|
||||||
)
|
|
||||||
'''
|
|
||||||
`
|
|
||||||
)
|
|
||||||
var (
|
|
||||||
db *sql.DB
|
|
||||||
)
|
|
||||||
|
|
||||||
func getDb(file string, init bool) (*sql.DB, error) {
|
|
||||||
log.Println("init database ", init)
|
|
||||||
if init {
|
|
||||||
log.Println("remove database file", file)
|
|
||||||
os.Remove(file)
|
|
||||||
}
|
|
||||||
db, err := sql.Open(DbDriver, file)
|
|
||||||
defer db.Close()
|
|
||||||
if err != nil {
|
|
||||||
log.Fatal("error in open database ", err)
|
|
||||||
}
|
|
||||||
_, err = db.Exec(TableCreate)
|
|
||||||
if err != nil {
|
|
||||||
log.Fatal("error in create telegram table", err)
|
|
||||||
}
|
|
||||||
return db, nil
|
|
||||||
}
|
|
||||||
@@ -5,6 +5,7 @@ go 1.15
|
|||||||
require (
|
require (
|
||||||
github.com/fsnotify/fsnotify v1.4.9 // indirect
|
github.com/fsnotify/fsnotify v1.4.9 // indirect
|
||||||
github.com/magiconair/properties v1.8.4 // indirect
|
github.com/magiconair/properties v1.8.4 // indirect
|
||||||
|
github.com/mattn/go-sqlite3 v1.14.5
|
||||||
github.com/mitchellh/mapstructure v1.4.0 // indirect
|
github.com/mitchellh/mapstructure v1.4.0 // indirect
|
||||||
github.com/pelletier/go-toml v1.8.1 // indirect
|
github.com/pelletier/go-toml v1.8.1 // indirect
|
||||||
github.com/spf13/afero v1.5.1 // indirect
|
github.com/spf13/afero v1.5.1 // indirect
|
||||||
|
|||||||
@@ -118,6 +118,8 @@ github.com/magiconair/properties v1.8.4 h1:8KGKTcQQGm0Kv7vEbKFErAoAOFyyacLStRtQS
|
|||||||
github.com/magiconair/properties v1.8.4/go.mod h1:y3VJvCyxH9uVvJTWEGAELF3aiYNyPKd5NZ3oSwXrF60=
|
github.com/magiconair/properties v1.8.4/go.mod h1:y3VJvCyxH9uVvJTWEGAELF3aiYNyPKd5NZ3oSwXrF60=
|
||||||
github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
|
github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
|
||||||
github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
|
github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
|
||||||
|
github.com/mattn/go-sqlite3 v1.14.5 h1:1IdxlwTNazvbKJQSxoJ5/9ECbEeaTTyeU7sEAZ5KKTQ=
|
||||||
|
github.com/mattn/go-sqlite3 v1.14.5/go.mod h1:WVKg1VTActs4Qso6iwGbiFih2UIHo0ENGwNd0Lj+XmI=
|
||||||
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
|
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
|
||||||
github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg=
|
github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg=
|
||||||
github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc=
|
github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc=
|
||||||
|
|||||||
@@ -2,7 +2,13 @@ serial:
|
|||||||
device: ttyS1
|
device: ttyS1
|
||||||
baudrate: 9600
|
baudrate: 9600
|
||||||
bytesize: 7
|
bytesize: 7
|
||||||
|
lograw: true
|
||||||
|
|
||||||
|
|
||||||
sqlite:
|
sqlite:
|
||||||
file: telegram.db
|
file: telegram.db
|
||||||
|
init: true
|
||||||
|
|
||||||
|
|
||||||
|
socket:
|
||||||
|
address: 127.0.0.1:6000
|
||||||
@@ -0,0 +1,48 @@
|
|||||||
|
package utils
|
||||||
|
|
||||||
|
import (
|
||||||
|
"io"
|
||||||
|
"log"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/tarm/serial"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
device string
|
||||||
|
baudrate int
|
||||||
|
bytesize byte
|
||||||
|
port *serial.Port
|
||||||
|
portOpened = false
|
||||||
|
)
|
||||||
|
|
||||||
|
func OpenPort(device string, baudrate int, bytesize byte) error {
|
||||||
|
log.Println("opening port device:", device, ", baudrate=", baudrate, ", bytesize=", bytesize)
|
||||||
|
config := &serial.Config{Name: device, Baud: baudrate, Size: bytesize, ReadTimeout: time.Second * 1}
|
||||||
|
var err error
|
||||||
|
port, err = serial.OpenPort(config)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatalln("error in open serial port ", err)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
log.Println("opened port ", port)
|
||||||
|
portOpened = true
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func ReadPort() ([]byte, int) {
|
||||||
|
buffer := make([]byte, 256)
|
||||||
|
if !ServerRunning {
|
||||||
|
return buffer, 0
|
||||||
|
}
|
||||||
|
count, err := port.Read(buffer)
|
||||||
|
if err != nil && err != io.EOF {
|
||||||
|
log.Println("error in read port ", err)
|
||||||
|
//TODO: 3 time fail try to
|
||||||
|
}
|
||||||
|
return buffer, count
|
||||||
|
}
|
||||||
|
|
||||||
|
func IsPortOpen() bool {
|
||||||
|
return portOpened
|
||||||
|
}
|
||||||
@@ -0,0 +1,87 @@
|
|||||||
|
package utils
|
||||||
|
|
||||||
|
import (
|
||||||
|
"io"
|
||||||
|
"log"
|
||||||
|
"net"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
const ServerType = "tcp"
|
||||||
|
|
||||||
|
var ServerRunning = false
|
||||||
|
var client net.Conn
|
||||||
|
var server net.Listener
|
||||||
|
var ClientReady = false
|
||||||
|
|
||||||
|
func Listen(address string) {
|
||||||
|
var err error
|
||||||
|
server, err = net.Listen(ServerType, address)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal("error in create server ", err)
|
||||||
|
}
|
||||||
|
defer server.Close()
|
||||||
|
log.Println("listen on ", address)
|
||||||
|
for ServerRunning {
|
||||||
|
conn, err := server.Accept()
|
||||||
|
if err != nil {
|
||||||
|
ServerRunning = false
|
||||||
|
log.Fatalln("error in create connection ", err)
|
||||||
|
}
|
||||||
|
if client == nil {
|
||||||
|
client = conn
|
||||||
|
ClientReady = false
|
||||||
|
log.Println("client connected ", client.RemoteAddr())
|
||||||
|
LoadUnprocessed()
|
||||||
|
} else {
|
||||||
|
log.Println("client already connected, close")
|
||||||
|
client.Close()
|
||||||
|
client = nil
|
||||||
|
conn.Close()
|
||||||
|
}
|
||||||
|
if IsClientConnected() {
|
||||||
|
connCheck()
|
||||||
|
}
|
||||||
|
time.Sleep(2 * time.Second)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func WriteToClient(data string) error {
|
||||||
|
_, err := client.Write([]byte(data + "\r\n"))
|
||||||
|
if err != nil {
|
||||||
|
log.Println("error in write data to client socket ", err)
|
||||||
|
closeClient()
|
||||||
|
}
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func connCheck() bool {
|
||||||
|
_, err := client.Read(make([]byte, 0))
|
||||||
|
if err != nil && err != io.EOF {
|
||||||
|
// this connection is invalid
|
||||||
|
log.Println("conn closed....", err)
|
||||||
|
client = nil
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
func IsClientConnected() bool {
|
||||||
|
return client != nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func closeClient() {
|
||||||
|
if client != nil {
|
||||||
|
client.Close()
|
||||||
|
client = nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func StopSocketServer() {
|
||||||
|
if IsClientConnected() {
|
||||||
|
client.Close()
|
||||||
|
}
|
||||||
|
if server != nil {
|
||||||
|
server.Close()
|
||||||
|
}
|
||||||
|
}
|
||||||
+176
@@ -0,0 +1,176 @@
|
|||||||
|
package utils
|
||||||
|
|
||||||
|
import (
|
||||||
|
"database/sql"
|
||||||
|
"log"
|
||||||
|
"os"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
_ "github.com/mattn/go-sqlite3"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
DbDriver = "sqlite3"
|
||||||
|
TableCreate = `
|
||||||
|
create table IF NOT EXISTS telegram (
|
||||||
|
[tele_id] INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||||
|
[tele_recv_time] TIMESTAMP NOT NULL DEFAULT (datetime('now', 'localtime')),
|
||||||
|
[tele_processed] int(1) NOT NULL DEFAULT 0,
|
||||||
|
[tele_text] TEXT NOT NULL
|
||||||
|
)
|
||||||
|
`
|
||||||
|
InsertNew = "insert into telegram (tele_text) values (?)"
|
||||||
|
InsertOld = "insert into telegram (tele_text, tele_processed) values (?, 1)"
|
||||||
|
|
||||||
|
count = "select count(*) from telegram where tele_processed=0"
|
||||||
|
load = "select tele_id, tele_text from telegram where tele_processed=0 Limit 100"
|
||||||
|
update = "update telegram set tele_processed = 1 where tele_id=?"
|
||||||
|
)
|
||||||
|
|
||||||
|
type telegram struct {
|
||||||
|
id int64
|
||||||
|
text string
|
||||||
|
}
|
||||||
|
|
||||||
|
var (
|
||||||
|
dbFile string
|
||||||
|
initTable bool
|
||||||
|
initialized bool
|
||||||
|
isWriting bool
|
||||||
|
)
|
||||||
|
|
||||||
|
func getDb() *sql.DB {
|
||||||
|
//log.Println("init database ", initTable)
|
||||||
|
if initTable && !initialized {
|
||||||
|
log.Println("remove database file", dbFile)
|
||||||
|
os.Remove(dbFile)
|
||||||
|
}
|
||||||
|
db, err := sql.Open(DbDriver, dbFile)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal("error in open database ", err)
|
||||||
|
}
|
||||||
|
return db
|
||||||
|
}
|
||||||
|
|
||||||
|
func InitDb(file string, init bool) error {
|
||||||
|
dbFile = file
|
||||||
|
initTable = init
|
||||||
|
var dbErr error
|
||||||
|
db := getDb()
|
||||||
|
defer db.Close()
|
||||||
|
_, dbErr = db.Exec(TableCreate)
|
||||||
|
checkDbErr(dbErr, "error in create table")
|
||||||
|
log.Println("database ", db, " initialized")
|
||||||
|
initialized = true
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func InsertTelegram(teleString string) {
|
||||||
|
getWriteLock()
|
||||||
|
db := getDb()
|
||||||
|
defer db.Close()
|
||||||
|
var insertSQL string
|
||||||
|
if ClientReady && WriteToClient(teleString) == nil {
|
||||||
|
insertSQL = InsertOld
|
||||||
|
} else {
|
||||||
|
insertSQL = InsertNew
|
||||||
|
}
|
||||||
|
stmt, _ := db.Prepare(insertSQL)
|
||||||
|
|
||||||
|
defer stmt.Close()
|
||||||
|
result, err := stmt.Exec(teleString)
|
||||||
|
id, _ := result.LastInsertId()
|
||||||
|
checkDbErr(err, "error in insert telegram ")
|
||||||
|
isWriting = false
|
||||||
|
if insertSQL == InsertOld {
|
||||||
|
log.Println("telegram processed ", id)
|
||||||
|
} else {
|
||||||
|
log.Println("telegram saved ", id)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func LoadUnprocessed() {
|
||||||
|
log.Println("loading telegram")
|
||||||
|
db := getDb()
|
||||||
|
defer db.Close()
|
||||||
|
for {
|
||||||
|
telegrams := getTelegram(db)
|
||||||
|
if len(telegrams) < 1 {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
for _, t := range telegrams {
|
||||||
|
if WriteToClient(t.text) == nil {
|
||||||
|
processed(db, t)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ClientReady = true
|
||||||
|
log.Println("client is ready for new telegram")
|
||||||
|
}
|
||||||
|
|
||||||
|
func getTelegram(db *sql.DB) []telegram {
|
||||||
|
var telegrams []telegram
|
||||||
|
num := countTelegram()
|
||||||
|
log.Println("unprocessed : ", num)
|
||||||
|
if num < 1 {
|
||||||
|
return telegrams
|
||||||
|
}
|
||||||
|
log.Println("try to load unprocessed telegram ", num)
|
||||||
|
rows, err := db.Query(load)
|
||||||
|
checkDbErr(err, "error in query telegram")
|
||||||
|
defer rows.Close()
|
||||||
|
for rows.Next() {
|
||||||
|
var t telegram
|
||||||
|
err := rows.Scan(&t.id, &t.text)
|
||||||
|
checkDbErr(err, "error in scan telegram")
|
||||||
|
telegrams = append(telegrams, t)
|
||||||
|
}
|
||||||
|
return telegrams
|
||||||
|
}
|
||||||
|
|
||||||
|
func processed(db *sql.DB, t telegram) {
|
||||||
|
getWriteLock()
|
||||||
|
tx, err := db.Begin()
|
||||||
|
checkDbErr(err, "error in begin update")
|
||||||
|
stmt, err := db.Prepare(update)
|
||||||
|
defer stmt.Close()
|
||||||
|
checkDbErr(err, "error in create update statement")
|
||||||
|
result, err := stmt.Exec(t.id)
|
||||||
|
checkDbErr(err, "error in update telegram status")
|
||||||
|
id, _ := result.RowsAffected()
|
||||||
|
log.Println(t.id, " telegram update : ", id > 0)
|
||||||
|
isWriting = false
|
||||||
|
log.Println("release lock")
|
||||||
|
tx.Commit()
|
||||||
|
}
|
||||||
|
|
||||||
|
func countTelegram() int64 {
|
||||||
|
db := getDb()
|
||||||
|
var countErr error
|
||||||
|
stmt, _ := db.Prepare(count)
|
||||||
|
defer stmt.Close()
|
||||||
|
var num int64
|
||||||
|
countErr = stmt.QueryRow().Scan(&num)
|
||||||
|
checkDbErr(countErr, "error in count telegram")
|
||||||
|
return num
|
||||||
|
}
|
||||||
|
|
||||||
|
func getWriteLock() {
|
||||||
|
count := 0
|
||||||
|
log.Println("write lock :", isWriting)
|
||||||
|
for isWriting && count < 10 {
|
||||||
|
log.Println("waiting for write ")
|
||||||
|
time.Sleep(5 * time.Second)
|
||||||
|
count++
|
||||||
|
}
|
||||||
|
if count >= 10 {
|
||||||
|
log.Fatalln("database locked")
|
||||||
|
}
|
||||||
|
isWriting = true
|
||||||
|
}
|
||||||
|
|
||||||
|
func checkDbErr(err error, msg string) {
|
||||||
|
if err != nil {
|
||||||
|
log.Fatalln(msg, err)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,37 @@
|
|||||||
|
package utils
|
||||||
|
|
||||||
|
import (
|
||||||
|
"log"
|
||||||
|
"regexp"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
EndTag = "NNNN"
|
||||||
|
Expression = "(?s)ZCZC.*NNNN"
|
||||||
|
)
|
||||||
|
|
||||||
|
var buffer []byte
|
||||||
|
|
||||||
|
func Append(data []byte) {
|
||||||
|
buffer = append(buffer, data...)
|
||||||
|
if buffer[len(buffer)-1] == '\r' {
|
||||||
|
buffer = append(buffer, '\n')
|
||||||
|
}
|
||||||
|
check()
|
||||||
|
}
|
||||||
|
|
||||||
|
func check() {
|
||||||
|
teleString := string(buffer)
|
||||||
|
if strings.Index(teleString, EndTag) > 0 {
|
||||||
|
exp, _ := regexp.Compile(Expression)
|
||||||
|
telegram := exp.FindString(string(buffer))
|
||||||
|
|
||||||
|
if len(telegram) > 0 {
|
||||||
|
log.Println("telegram : ", telegram)
|
||||||
|
buffer = nil
|
||||||
|
InsertTelegram(telegram)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user