mirror of
https://github.com/MickMake/GoSungrow.git
synced 2025-03-26 17:41:42 +01:00
v2.3.6 - Rename GoStruct
This commit is contained in:
parent
c02eacf369
commit
260fd19728
115
iSolarCloud/api/GoStruct/const.go
Normal file
115
iSolarCloud/api/GoStruct/const.go
Normal file
@ -0,0 +1,115 @@
|
||||
package GoStruct
|
||||
|
||||
// These are tags that can be added to a Go structure that GoStruct uses to process the structure.
|
||||
|
||||
|
||||
const (
|
||||
// NameGoStruct - Name of field within structure that allows for assigning tags to the parent.
|
||||
// Add like this:
|
||||
// type ResultData []struct {
|
||||
// GoStruct GoStruct.GoStruct `json:"GoStruct" DataTable:"true" DataTableSortOn:"UnitConvertId"`
|
||||
NameGoStruct = "GoStruct"
|
||||
|
||||
// PointId - Point id in the form p\d+ or \d+ or free-form text.
|
||||
PointId = "PointId"
|
||||
|
||||
// PointParentId - Associated parent of point.
|
||||
PointParentId = "PointParentId"
|
||||
|
||||
// PointUpdateFreq - Point update frequency - Total, Yearly, Monthly, Day.
|
||||
PointUpdateFreq = "PointUpdateFreq"
|
||||
UpdateFreqInstant = "instant"
|
||||
UpdateFreq5Mins = "5mins"
|
||||
UpdateFreqBoot = "boot"
|
||||
UpdateFreqDay = "daily"
|
||||
UpdateFreqMonth = "monthly"
|
||||
UpdateFreqYear = "yearly"
|
||||
UpdateFreqTotal = "total"
|
||||
|
||||
// PointValueType - Value type of point: energy, date, battery, temperature.
|
||||
PointValueType = "PointValueType"
|
||||
|
||||
// PointIgnore - Ignore this point.
|
||||
PointIgnore = "PointIgnore"
|
||||
|
||||
// PointIgnoreIfNil - Ignore this point if a child is nil or empty.
|
||||
PointIgnoreIfNil = "PointIgnoreIfNil"
|
||||
|
||||
// PointIgnoreIfNilFromChild - Ignore this point if a child is nil or empty.
|
||||
PointIgnoreIfNilFromChild = "PointIgnoreIfNilFromChild"
|
||||
|
||||
// PointAliasTo - Alias this point to another point.
|
||||
PointAliasTo = "PointAliasTo"
|
||||
|
||||
// PointAliasFrom - Alias this point from another point.
|
||||
PointAliasFrom = "PointAliasFrom"
|
||||
|
||||
// PointUnit - Units: Wh, kWh, C, h.
|
||||
PointUnit = "PointUnit"
|
||||
|
||||
// PointUnitFrom - Get PointUnit from another field structure.
|
||||
PointUnitFrom = "PointUnitFrom"
|
||||
|
||||
// PointUnitFromParent - Get PointUnit from another parent field structure.
|
||||
PointUnitFromParent = "PointUnitFromParent"
|
||||
|
||||
// PointGroupName - Point group name.
|
||||
PointGroupName = "PointGroupName"
|
||||
|
||||
// PointGroupNameFrom - Get PointGroupName from another field structure.
|
||||
PointGroupNameFrom = "PointGroupNameFrom"
|
||||
|
||||
// PointName - Human-readable name of point.
|
||||
PointName = "PointName"
|
||||
|
||||
// PointNameFromChild - Searches child for field value to use for naming when hitting a slice, (as opposed to using an index).
|
||||
PointNameFromChild = "PointNameFromChild"
|
||||
|
||||
// PointNameFromParent - Searches child for field value to use for naming when hitting a slice, (as opposed to using an index).
|
||||
PointNameFromParent = "PointNameFromParent"
|
||||
|
||||
// PointNameDateFormat - Date format when using PointNameFrom, (if the field is a time.Time type).
|
||||
PointNameDateFormat = "PointNameDateFormat"
|
||||
|
||||
// PointNameAppend - Append PointNameFrom instead of replace.
|
||||
PointNameAppend = "PointNameAppend"
|
||||
|
||||
// PointArrayFlatten - Flatten an array into a string. EG: ["one", "two", "three"]
|
||||
PointArrayFlatten = "PointArrayFlatten"
|
||||
|
||||
// PointSplitOn - Split a point into an array separating by defined string.
|
||||
PointSplitOn = "PointSplitOn"
|
||||
|
||||
// PointSplitOnType - What valueTypes will be used for a split.
|
||||
PointSplitOnType = "PointSplitOnType"
|
||||
|
||||
// PointIgnoreZero - Ignore arrays with zero size, (default true).
|
||||
PointIgnoreZero = "PointIgnoreZero"
|
||||
|
||||
// PointTimestampFrom - Pull timestamp from another field structure.
|
||||
PointTimestampFrom = "PointTimestampFrom"
|
||||
|
||||
// IsDataTable - This entity is a data table - Will only traverse down one child.
|
||||
IsDataTable = "DataTable"
|
||||
|
||||
// DataTableId - Table id, (defaults to Json tag).
|
||||
DataTableId = "DataTableId"
|
||||
|
||||
// DataTableName - Table Name, (defaults to DataTableId).
|
||||
DataTableName = "DataTableName"
|
||||
|
||||
// DataTableTitle - Table Title, (defaults to DataTableId in name format).
|
||||
DataTableTitle = "DataTableTitle"
|
||||
|
||||
// DataTableMerge - Merge rows together - useful for when we use, for EG: []valueTypes.Float
|
||||
DataTableMerge = "DataTableMerge"
|
||||
|
||||
// DataTableShowIndex - Show index on table.
|
||||
DataTableShowIndex = "DataTableShowIndex"
|
||||
|
||||
// DataTableSortOn - Sort table using this Field.
|
||||
DataTableSortOn = "DataTableSortOn"
|
||||
|
||||
)
|
||||
|
||||
type GoStruct bool
|
@ -1,5 +1,5 @@
|
||||
// Package apiReflect - Snaffooed from https://github.com/fatih/structs
|
||||
package apiReflect
|
||||
// Package GoStruct - Snaffooed from https://github.com/fatih/structs
|
||||
package GoStruct
|
||||
|
||||
import (
|
||||
"errors"
|
@ -7,22 +7,22 @@ import (
|
||||
"fmt"
|
||||
"github.com/wcharczuk/go-chart/v2"
|
||||
"github.com/wcharczuk/go-chart/v2/drawing"
|
||||
"go.pennock.tech/tabular"
|
||||
"os"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
// "go.pennock.tech/tabular"
|
||||
// tabular "github.com/agrison/go-tablib"
|
||||
|
||||
type GraphRequest struct {
|
||||
Title string `json:"title"`
|
||||
|
||||
TimeColumn *int `json:"time_column"`
|
||||
ValueColumn *int `json:"value_column"`
|
||||
UnitsColumn *int `json:"units_column"`
|
||||
NameColumn *int `json:"name_column"`
|
||||
SearchColumn *int `json:"search_column"`
|
||||
TimeColumn *string `json:"time_column"`
|
||||
ValueColumn *string `json:"value_column"`
|
||||
UnitsColumn *string `json:"units_column"`
|
||||
NameColumn *string `json:"name_column"`
|
||||
SearchColumn *string `json:"search_column"`
|
||||
SearchString *string `json:"search_string"`
|
||||
|
||||
MinLeftAxis *float64 `json:"min_left_axis"`
|
||||
@ -130,67 +130,72 @@ func (t *Table) GetSearchColumn() SearchStrings {
|
||||
|
||||
func (t *Table) ProcessGraphData() error {
|
||||
for range Only.Once {
|
||||
fmt.Println("This is currently broken!")
|
||||
break
|
||||
req := t.graph.req
|
||||
|
||||
t.graph.searchName = ""
|
||||
var units string
|
||||
var times []time.Time
|
||||
var values []float64
|
||||
for row := 0; row < t.table.NRows(); row++ {
|
||||
for row := 0; row < t.RowLength(); row++ {
|
||||
// Get the search column
|
||||
var cell *tabular.Cell
|
||||
cell, t.Error = t.table.CellAt(tabular.CellLocation{Row: row, Column: *req.SearchColumn})
|
||||
var cell interface{}
|
||||
// cell, t.Error = t.table.CellAt(tabular.CellLocation{Row: row, Column: *req.SearchColumn})
|
||||
cell, t.Error = t.GetCell(row, *req.SearchColumn)
|
||||
if t.Error != nil {
|
||||
continue
|
||||
}
|
||||
if !strings.Contains(cell.String(), *req.SearchString) {
|
||||
continue
|
||||
}
|
||||
// if !strings.Contains(cell.String(), *req.SearchString) {
|
||||
// continue
|
||||
// }
|
||||
|
||||
if req.Title == "" {
|
||||
t.SetTitle(cell.String())
|
||||
t.SetTitle(cell.(string))
|
||||
}
|
||||
|
||||
if t.graph.searchName == "" {
|
||||
if *req.NameColumn > 0 {
|
||||
cell, t.Error = t.table.CellAt(tabular.CellLocation{Row: row, Column: *req.NameColumn})
|
||||
if req.NameColumn != nil {
|
||||
// cell, t.Error = t.table.CellAt(tabular.CellLocation{Row: row, Column: *req.NameColumn})
|
||||
cell, t.Error = t.GetCell(row, *req.NameColumn)
|
||||
if t.Error != nil {
|
||||
continue
|
||||
}
|
||||
t.graph.searchName = cell.String()
|
||||
t.graph.searchName = cell.(string)
|
||||
}
|
||||
}
|
||||
|
||||
// Get units
|
||||
if units == "" {
|
||||
if *req.UnitsColumn > 0 {
|
||||
cell, t.Error = t.table.CellAt(tabular.CellLocation{Row: row, Column: *req.UnitsColumn})
|
||||
if req.UnitsColumn != nil {
|
||||
// cell, t.Error = t.table.CellAt(tabular.CellLocation{Row: row, Column: *req.UnitsColumn})
|
||||
cell, t.Error = t.GetCell(row, *req.UnitsColumn)
|
||||
if t.Error != nil {
|
||||
continue
|
||||
}
|
||||
units = cell.String()
|
||||
units = cell.(string)
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
cell, t.Error = t.table.CellAt(tabular.CellLocation{Row: row, Column: *req.TimeColumn})
|
||||
// cell, t.Error = t.table.CellAt(tabular.CellLocation{Row: row, Column: *req.TimeColumn})
|
||||
cell, t.Error = t.GetCell(row, *req.TimeColumn)
|
||||
if t.Error != nil {
|
||||
continue
|
||||
}
|
||||
var tim time.Time
|
||||
tim, t.Error = time.ParseInLocation(DateTimeSearchLayout, cell.String(), time.Local) // @TODO - May have to revisit this!
|
||||
tim, t.Error = time.ParseInLocation(DateTimeSearchLayout, cell.(string), time.Local) // @TODO - May have to revisit this!
|
||||
if t.Error != nil {
|
||||
continue
|
||||
}
|
||||
times = append(times, tim)
|
||||
|
||||
//
|
||||
cell, t.Error = t.table.CellAt(tabular.CellLocation{Row: row, Column: *req.ValueColumn})
|
||||
// cell, t.Error = t.table.CellAt(tabular.CellLocation{Row: row, Column: *req.ValueColumn})
|
||||
cell, t.Error = t.GetCell(row, *req.ValueColumn)
|
||||
if t.Error != nil {
|
||||
continue
|
||||
}
|
||||
var val float64
|
||||
val, t.Error = strconv.ParseFloat(cell.String(), 64)
|
||||
val, t.Error = strconv.ParseFloat(cell.(string), 64)
|
||||
if t.Error != nil {
|
||||
val = 0
|
||||
}
|
||||
@ -219,19 +224,22 @@ func (t *Table) ProcessGraphData() error {
|
||||
type SearchStrings map[string]int
|
||||
func (t *Table) FindSearchStrings() error {
|
||||
for range Only.Once {
|
||||
fmt.Println("This is currently broken!")
|
||||
break
|
||||
t.graph.otherSearch = make(SearchStrings)
|
||||
|
||||
for row := 0; row < t.table.NRows(); row++ {
|
||||
for row := 0; row < t.RowLength(); row++ {
|
||||
// Get the search column
|
||||
var cell *tabular.Cell
|
||||
cell, t.Error = t.table.CellAt(tabular.CellLocation{Row: row, Column: *t.graph.req.SearchColumn})
|
||||
var cell interface{}
|
||||
// cell, t.Error = t.table.CellAt(tabular.CellLocation{Row: row, Column: *t.graph.req.SearchColumn})
|
||||
cell, t.Error = t.GetCell(row, *t.graph.req.SearchColumn)
|
||||
if t.Error != nil {
|
||||
continue
|
||||
}
|
||||
if _, ok := t.graph.otherSearch[cell.String()]; ok {
|
||||
t.graph.otherSearch[cell.String()] += 1
|
||||
if _, ok := t.graph.otherSearch[cell.(string)]; ok {
|
||||
t.graph.otherSearch[cell.(string)] += 1
|
||||
} else {
|
||||
t.graph.otherSearch[cell.String()] = 0
|
||||
t.graph.otherSearch[cell.(string)] = 0
|
||||
}
|
||||
}
|
||||
}
|
@ -2,7 +2,7 @@ package output
|
||||
|
||||
import (
|
||||
"GoSungrow/Only"
|
||||
"GoSungrow/iSolarCloud/api/apiReflect"
|
||||
"GoSungrow/iSolarCloud/api/GoStruct/reflection"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
)
|
||||
@ -50,7 +50,7 @@ func GetAsString(r interface{}) string {
|
||||
break
|
||||
}
|
||||
|
||||
a, e := apiReflect.GetStructName(r)
|
||||
a, e := reflection.GetStructName(r)
|
||||
ret += fmt.Sprintf(`"%s.%s": %s`, a, e, j)
|
||||
}
|
||||
return ret
|
||||
@ -65,7 +65,7 @@ func GetRequestString(r interface{}) string {
|
||||
break
|
||||
}
|
||||
|
||||
a, e := apiReflect.GetStructName(r)
|
||||
a, e := reflection.GetStructName(r)
|
||||
ret += fmt.Sprintf(`"%s.%s": %s`, a, e, j)
|
||||
}
|
||||
return ret
|
349
iSolarCloud/api/GoStruct/output/struct_table.go
Normal file
349
iSolarCloud/api/GoStruct/output/struct_table.go
Normal file
@ -0,0 +1,349 @@
|
||||
package output
|
||||
|
||||
import (
|
||||
"GoSungrow/Only"
|
||||
"errors"
|
||||
"fmt"
|
||||
tabular "github.com/agrison/go-tablib"
|
||||
"os"
|
||||
)
|
||||
// "github.com/agrison/go-tablib"
|
||||
// "go.pennock.tech/tabular"
|
||||
// "github.com/jbub/tabular"
|
||||
|
||||
|
||||
type Table struct {
|
||||
filePrefix string
|
||||
title string
|
||||
table *tabular.Dataset
|
||||
graph *Chart
|
||||
json []byte
|
||||
raw []byte
|
||||
OutputType OutputType
|
||||
saveAsFile bool
|
||||
graphFilter string
|
||||
Error error
|
||||
}
|
||||
type Tables map[string]Table
|
||||
|
||||
|
||||
func NewTable(headers ...string) Table {
|
||||
return Table {
|
||||
filePrefix: "",
|
||||
title: "",
|
||||
table: tabular.NewDataset(headers),
|
||||
Error: nil,
|
||||
}
|
||||
}
|
||||
|
||||
func NewTables() Tables {
|
||||
return make(Tables)
|
||||
}
|
||||
|
||||
func (t *Table) String() string {
|
||||
var ret string
|
||||
for range Only.Once {
|
||||
if t == nil {
|
||||
break
|
||||
}
|
||||
|
||||
if !t.table.Valid() {
|
||||
break
|
||||
}
|
||||
|
||||
ret = t.table.Tabular("grid").String()
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
||||
func (t *Table) GetHeaders() []string {
|
||||
return t.table.Headers()
|
||||
}
|
||||
|
||||
func (t *Table) RowLength() int {
|
||||
return t.table.Height()
|
||||
}
|
||||
|
||||
func (t *Table) GetCell(row int, colName string) (interface{}, error) {
|
||||
var ret interface{}
|
||||
for range Only.Once {
|
||||
var r map[string]interface{}
|
||||
r, t.Error = t.table.Row(row)
|
||||
if t.Error != nil {
|
||||
break
|
||||
}
|
||||
ret = r[colName]
|
||||
}
|
||||
return ret, t.Error
|
||||
}
|
||||
|
||||
// func (t *Table) AllRows() []*tabular.Row {
|
||||
// return t.table.AllRows()
|
||||
// }
|
||||
|
||||
type DataSet []DataRow
|
||||
type DataRow map[string]string
|
||||
|
||||
func (t *Table) SetTitle(title string, args ...interface{}) {
|
||||
t.title = fmt.Sprintf(title, args...)
|
||||
}
|
||||
|
||||
func (t *Table) SetRaw(data []byte) {
|
||||
t.raw = data
|
||||
}
|
||||
|
||||
func (t *Table) AppendRaw(data []byte) {
|
||||
t.raw = append(t.raw, data...)
|
||||
}
|
||||
|
||||
func (t *Table) SetJson(data []byte) {
|
||||
t.json = data
|
||||
}
|
||||
|
||||
func (t *Table) SetSaveFile(ok bool) {
|
||||
t.saveAsFile = ok
|
||||
}
|
||||
|
||||
func (t *Table) SetGraphFilter(filter string) {
|
||||
t.graphFilter = filter
|
||||
}
|
||||
|
||||
func (t *Table) Sort(sort string) {
|
||||
for range Only.Once {
|
||||
if t.IsNotValid() {
|
||||
break
|
||||
}
|
||||
|
||||
// Make sure we have a header.
|
||||
for _, header := range t.table.Headers() {
|
||||
if header == sort {
|
||||
t.table = t.table.Sort(sort)
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (t *Table) IsValid() bool {
|
||||
var yes bool
|
||||
for range Only.Once {
|
||||
if t.table == nil {
|
||||
break
|
||||
}
|
||||
if !t.table.Valid() {
|
||||
break
|
||||
}
|
||||
if t.table.Height() == 0 {
|
||||
break
|
||||
}
|
||||
if t.table.Width() == 0 {
|
||||
break
|
||||
}
|
||||
yes = true
|
||||
}
|
||||
return yes
|
||||
}
|
||||
|
||||
func (t *Table) IsNotValid() bool {
|
||||
return !t.IsValid()
|
||||
}
|
||||
|
||||
func (t *Table) SetFilePrefix(prefix string, args ...interface{}) {
|
||||
if len(args) == 0 {
|
||||
t.filePrefix = prefix
|
||||
return
|
||||
}
|
||||
t.filePrefix = fmt.Sprintf(prefix, args...)
|
||||
}
|
||||
|
||||
func (t *Table) SetOutputType(outputType string) {
|
||||
t.OutputType.Set(outputType)
|
||||
}
|
||||
|
||||
func (t *Table) AddRow(row ...interface{}) error {
|
||||
t.Error = t.table.Append(row)
|
||||
return t.Error
|
||||
}
|
||||
|
||||
func (t *Table) writeFile(fn string, data string, perm os.FileMode) error {
|
||||
for range Only.Once {
|
||||
fmt.Printf("Writing file '%s'\n", fn)
|
||||
t.Error = os.WriteFile(fn, []byte(data), perm)
|
||||
if t.Error != nil {
|
||||
t.Error = errors.New(fmt.Sprintf("Unable to write to file %s - %v", fn, t.Error))
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
return t.Error
|
||||
}
|
||||
|
||||
|
||||
func (t *Table) Output() error {
|
||||
for range Only.Once {
|
||||
if t == nil {
|
||||
break
|
||||
}
|
||||
|
||||
switch {
|
||||
case t.OutputType.IsNone():
|
||||
|
||||
case t.OutputType.IsTable():
|
||||
t.Error = t.WriteTable()
|
||||
|
||||
case t.OutputType.IsList():
|
||||
t.Error = t.WriteList()
|
||||
|
||||
case t.OutputType.IsCsv():
|
||||
t.Error = t.WriteCsv()
|
||||
|
||||
case t.OutputType.IsRaw():
|
||||
t.Error = t.WriteRaw()
|
||||
|
||||
case t.OutputType.IsJson():
|
||||
t.Error = t.WriteJson()
|
||||
|
||||
case t.OutputType.IsGraph():
|
||||
t.Error = t.SetGraphFromJson(Json(t.graphFilter))
|
||||
if t.Error != nil {
|
||||
break
|
||||
}
|
||||
t.Error = t.CreateGraph()
|
||||
if t.Error != nil {
|
||||
break
|
||||
}
|
||||
|
||||
default:
|
||||
}
|
||||
}
|
||||
|
||||
return t.Error
|
||||
}
|
||||
|
||||
func (t *Table) GetTable() string {
|
||||
return t.String()
|
||||
}
|
||||
|
||||
func (t *Table) WriteTable() error {
|
||||
for range Only.Once {
|
||||
if t.IsNotValid() {
|
||||
break
|
||||
}
|
||||
|
||||
if t.saveAsFile {
|
||||
t.Error = t.writeFile(t.filePrefix+"-table.txt", t.String(), DefaultFileMode)
|
||||
}
|
||||
fmt.Printf("# %s\n", t.title)
|
||||
fmt.Print(t.String())
|
||||
}
|
||||
return t.Error
|
||||
}
|
||||
|
||||
func (t *Table) WriteList() error {
|
||||
for range Only.Once {
|
||||
if t.IsNotValid() {
|
||||
break
|
||||
}
|
||||
|
||||
if t.saveAsFile {
|
||||
t.Error = t.writeFile(t.filePrefix+".txt", t.String(), DefaultFileMode)
|
||||
}
|
||||
fmt.Printf("# %s\n", t.title)
|
||||
fmt.Print(t.String())
|
||||
}
|
||||
return t.Error
|
||||
}
|
||||
|
||||
|
||||
func (t *Table) GetCsv() string {
|
||||
var ret string
|
||||
for range Only.Once {
|
||||
if t.IsNotValid() {
|
||||
break
|
||||
}
|
||||
|
||||
var result *tabular.Exportable
|
||||
result, t.Error = t.table.CSV()
|
||||
if t.Error != nil {
|
||||
break
|
||||
}
|
||||
ret = result.String()
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
||||
func (t *Table) WriteCsv() error {
|
||||
for range Only.Once {
|
||||
if t.saveAsFile {
|
||||
t.Error = t.writeFile(t.filePrefix+".csv", t.GetCsv(), DefaultFileMode)
|
||||
break
|
||||
}
|
||||
fmt.Print(t.GetCsv())
|
||||
}
|
||||
return t.Error
|
||||
}
|
||||
|
||||
|
||||
func (t *Table) GetXml() string {
|
||||
var ret string
|
||||
for range Only.Once {
|
||||
if t.IsNotValid() {
|
||||
break
|
||||
}
|
||||
|
||||
var result *tabular.Exportable
|
||||
result, t.Error = t.table.CSV()
|
||||
if t.Error != nil {
|
||||
break
|
||||
}
|
||||
ret = result.String()
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
||||
func (t *Table) WriteXml() error {
|
||||
for range Only.Once {
|
||||
if t.saveAsFile {
|
||||
t.Error = t.writeFile(t.filePrefix+".xml", t.GetXml(), DefaultFileMode)
|
||||
break
|
||||
}
|
||||
fmt.Print(t.GetXml())
|
||||
}
|
||||
return t.Error
|
||||
}
|
||||
|
||||
|
||||
func (t *Table) GetJson() string {
|
||||
return string(t.raw)
|
||||
}
|
||||
|
||||
func (t *Table) WriteJson() error {
|
||||
for range Only.Once {
|
||||
if t.saveAsFile {
|
||||
t.Error = t.writeFile(t.filePrefix + ".json", string(t.json), DefaultFileMode)
|
||||
break
|
||||
}
|
||||
fmt.Printf("%s", t.json)
|
||||
}
|
||||
return t.Error
|
||||
}
|
||||
|
||||
|
||||
func (t *Table) GetRaw() string {
|
||||
return string(t.json)
|
||||
}
|
||||
|
||||
func (t *Table) GetRawBytes() []byte {
|
||||
return t.json
|
||||
}
|
||||
|
||||
func (t *Table) WriteRaw() error {
|
||||
for range Only.Once {
|
||||
if t.saveAsFile {
|
||||
t.Error = t.writeFile(t.filePrefix+".raw", string(t.raw), DefaultFileMode)
|
||||
break
|
||||
}
|
||||
fmt.Printf("%s", t.raw)
|
||||
}
|
||||
return t.Error
|
||||
}
|
318
iSolarCloud/api/GoStruct/reflection/funcs.go
Normal file
318
iSolarCloud/api/GoStruct/reflection/funcs.go
Normal file
@ -0,0 +1,318 @@
|
||||
package reflection
|
||||
|
||||
import (
|
||||
"GoSungrow/iSolarCloud/api/GoStruct/valueTypes"
|
||||
"crypto/md5"
|
||||
"errors"
|
||||
"fmt"
|
||||
"github.com/MickMake/GoUnify/Only"
|
||||
"reflect"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
|
||||
func GetPointNameFrom(ref interface{}, name string, intSize int, dateFormat string) string {
|
||||
var ret string
|
||||
for range Only.Once {
|
||||
if dateFormat == "" {
|
||||
dateFormat = valueTypes.DateTimeAltLayout
|
||||
}
|
||||
vo := reflect.ValueOf(ref)
|
||||
|
||||
var ra []string
|
||||
switch vo.Kind() {
|
||||
case reflect.Struct:
|
||||
for _, pnf := range strings.Split(name, ".") {
|
||||
// Iterate over all available fields, looking for the field name.
|
||||
for i := 0; i < vo.NumField(); i++ {
|
||||
fn := vo.Type().Field(i).Name
|
||||
if fn == pnf {
|
||||
ra = append(ra, valueTypes.AnyToValueString(vo.Field(i).Interface(), intSize, dateFormat))
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
case reflect.Map:
|
||||
for _, pnf := range strings.Split(name, ".") {
|
||||
// Iterate over all available keys, looking for the key name.
|
||||
for _, key := range vo.MapKeys() {
|
||||
if key.String() == pnf {
|
||||
ra = append(ra, valueTypes.AnyToValueString(vo.MapIndex(key).Interface(), intSize, dateFormat))
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
ret = strings.Join(ra, ".")
|
||||
}
|
||||
|
||||
return ret
|
||||
}
|
||||
|
||||
func GetStringFrom(ref interface{}, name string) string {
|
||||
var ret string
|
||||
for range Only.Once {
|
||||
vo := reflect.ValueOf(ref)
|
||||
|
||||
switch vo.Kind() {
|
||||
case reflect.Struct:
|
||||
// Iterate over all available fields, looking for the field name.
|
||||
for i := 0; i < vo.NumField(); i++ {
|
||||
if vo.Type().Field(i).Name == name {
|
||||
ret = valueTypes.AnyToValueString(vo.Field(i).Interface(), 0, "")
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
case reflect.Map:
|
||||
// Iterate over all available fields, looking for the field name.
|
||||
for _, key := range vo.MapKeys() {
|
||||
if key.String() == name {
|
||||
ret = valueTypes.AnyToValueString(vo.MapIndex(key).Interface(), 0, "")
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ret
|
||||
}
|
||||
|
||||
func GetJsonTag(fieldTo reflect.StructField) string {
|
||||
var ret string
|
||||
|
||||
for range Only.Once {
|
||||
ret = fieldTo.Tag.Get("json")
|
||||
ret = strings.ReplaceAll(ret, "omitempty", "")
|
||||
ret = strings.TrimSuffix(ret, ",")
|
||||
}
|
||||
|
||||
return ret
|
||||
}
|
||||
|
||||
func GetTimestampFrom(ref interface{}, name string, dateFormat string) time.Time {
|
||||
var ret time.Time
|
||||
for range Only.Once {
|
||||
if dateFormat == "" {
|
||||
dateFormat = valueTypes.DateTimeAltLayout
|
||||
}
|
||||
vo := reflect.ValueOf(ref)
|
||||
|
||||
switch vo.Kind() {
|
||||
case reflect.Struct:
|
||||
// Iterate over all available fields, looking for the field name.
|
||||
for i := 0; i < vo.NumField(); i++ {
|
||||
if vo.Type().Field(i).Name == name {
|
||||
v := fmt.Sprintf("%v", vo.Field(i).Interface())
|
||||
ret = valueTypes.SetDateTimeString(v).Time
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
case reflect.Map:
|
||||
// Iterate over all available fields, looking for the field name.
|
||||
for _, key := range vo.MapKeys() {
|
||||
if key.String() == name {
|
||||
v := fmt.Sprintf("%v", vo.MapIndex(key).Interface())
|
||||
ret = valueTypes.SetDateTimeString(v).Time
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ret
|
||||
}
|
||||
|
||||
func GetFingerprint(ref interface{}) string {
|
||||
var ret string
|
||||
|
||||
for range Only.Once {
|
||||
// h := hash(GetRequestString(ref))
|
||||
h := md5.Sum([]byte(GetRequestString(ref)))
|
||||
ret = fmt.Sprintf("%x", h)
|
||||
}
|
||||
|
||||
return ret
|
||||
}
|
||||
|
||||
func GetRequestString(ref interface{}) string {
|
||||
var ret string
|
||||
|
||||
for range Only.Once {
|
||||
vo := reflect.ValueOf(ref)
|
||||
// Iterate over all available fields and read the tag value
|
||||
for i := 0; i < vo.NumField(); i++ {
|
||||
fieldVo := vo.Field(i)
|
||||
ret += fmt.Sprintf("-%v", fieldVo.Interface())
|
||||
}
|
||||
}
|
||||
|
||||
return ret
|
||||
}
|
||||
|
||||
|
||||
// GetArea Return an Area name if we are given an Area or EndPoint struct.
|
||||
func GetArea(trim string, v interface{}) string {
|
||||
var ret string
|
||||
for range Only.Once {
|
||||
if v == nil {
|
||||
break
|
||||
}
|
||||
|
||||
val := reflect.ValueOf(v)
|
||||
ret1 := val.Type().PkgPath()
|
||||
ret1 = strings.TrimPrefix(ret1, trim)
|
||||
ret2 := val.Type().Name()
|
||||
|
||||
if ret2 == "Area" {
|
||||
s := strings.Split(ret1, "/")
|
||||
ret = s[len(s)-1]
|
||||
break
|
||||
}
|
||||
|
||||
if ret2 == "EndPoint" {
|
||||
s := strings.Split(ret1, "/")
|
||||
ret = s[len(s)-2]
|
||||
break
|
||||
}
|
||||
|
||||
ret = ret1
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
||||
// GetName Return an endpoint name if we are given an Area or EndPoint struct.
|
||||
func GetName(trim string, v interface{}) string {
|
||||
var ret string
|
||||
for range Only.Once {
|
||||
val := reflect.ValueOf(v)
|
||||
ret1 := val.Type().PkgPath()
|
||||
ret1 = strings.TrimPrefix(ret1, trim)
|
||||
ret2 := val.Type().Name()
|
||||
|
||||
if ret2 == "Area" {
|
||||
s := strings.Split(ret1, "/")
|
||||
ret = s[len(s)-2]
|
||||
break
|
||||
}
|
||||
|
||||
if ret2 == "EndPoint" {
|
||||
s := strings.Split(ret1, "/")
|
||||
ret = s[len(s)-1]
|
||||
break
|
||||
}
|
||||
|
||||
ret = ret1
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
||||
func HelpOptions(ref interface{}) string {
|
||||
var ret string
|
||||
|
||||
for range Only.Once {
|
||||
t := reflect.TypeOf(ref)
|
||||
for i := 0; i < t.NumField(); i++ {
|
||||
field := t.Field(i)
|
||||
required := field.Tag.Get("required")
|
||||
if required == "" {
|
||||
ret += fmt.Sprintf("%s: optional\n", field.Name)
|
||||
continue
|
||||
}
|
||||
|
||||
ret += fmt.Sprintf("%s: required\n", field.Name)
|
||||
}
|
||||
}
|
||||
|
||||
return ret
|
||||
}
|
||||
|
||||
|
||||
func GetStructName(v interface{}) (string, string) {
|
||||
var area string
|
||||
var endpoint string
|
||||
for range Only.Once {
|
||||
val := reflect.ValueOf(v)
|
||||
// ret = val.Type().Name() // Returns structure, (EndPoint name).
|
||||
// ret = val.Type().PkgPath() // Returns structure path.
|
||||
// ret = val.Type().String() // Returns
|
||||
|
||||
// @TODO - Need to check for pointers to struct
|
||||
// if t := reflect.TypeOf(ref); t.Kind() == reflect.Ptr {
|
||||
// ret = strings.ToLower(t.Elem().Name())
|
||||
// } else {
|
||||
// ret = strings.ToLower(t.Name())
|
||||
// }
|
||||
|
||||
s := strings.Split(val.Type().String(), ".")
|
||||
if len(s) < 2 {
|
||||
break
|
||||
}
|
||||
area = s[0]
|
||||
endpoint = s[1]
|
||||
}
|
||||
return area, endpoint
|
||||
}
|
||||
|
||||
func FindRequestData(ref interface{}) string {
|
||||
var ret string
|
||||
|
||||
for range Only.Once {
|
||||
vo := reflect.ValueOf(ref)
|
||||
to := reflect.TypeOf(ref)
|
||||
|
||||
// Iterate over all available fields and read the tag value
|
||||
for i := 0; i < vo.NumField(); i++ {
|
||||
fieldTo := to.Field(i)
|
||||
// required := fieldTo.Tag.GetByJson("required")
|
||||
fmt.Printf(">%s\t", fieldTo.Name)
|
||||
|
||||
fieldVo := vo.Field(i)
|
||||
|
||||
fmt.Printf(">%s\n", fieldVo.String())
|
||||
value := fmt.Sprintf("%v", fieldVo.Interface())
|
||||
if value == "" {
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ret
|
||||
}
|
||||
|
||||
func GetType(v interface{}) string {
|
||||
return reflect.ValueOf(v).Type().Name()
|
||||
}
|
||||
|
||||
func GetPkgType(v interface{}) string {
|
||||
return reflect.ValueOf(v).Type().String()
|
||||
}
|
||||
|
||||
func DoTypesMatch(a interface{}, b interface{}) error {
|
||||
var err error
|
||||
for range Only.Once {
|
||||
aName := GetType(a)
|
||||
bName := GetType(b)
|
||||
if aName == bName {
|
||||
break
|
||||
}
|
||||
err = errors.New(fmt.Sprintf("interface '%s' doesn't match '%s'", aName, bName))
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
func DoPkgTypesMatch(a interface{}, b interface{}) error {
|
||||
var err error
|
||||
for range Only.Once {
|
||||
aName := GetPkgType(a)
|
||||
bName := GetPkgType(b)
|
||||
if aName == bName {
|
||||
break
|
||||
}
|
||||
err = errors.New(fmt.Sprintf("interface '%s' doesn't match '%s'", aName, bName))
|
||||
}
|
||||
return err
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
package apiReflect
|
||||
package reflection
|
||||
|
||||
|
||||
// type StructKey struct {
|
@ -1,7 +1,8 @@
|
||||
package apiReflect
|
||||
package GoStruct
|
||||
|
||||
import (
|
||||
"GoSungrow/iSolarCloud/api/valueTypes"
|
||||
"GoSungrow/iSolarCloud/api/GoStruct/reflection"
|
||||
"GoSungrow/iSolarCloud/api/GoStruct/valueTypes"
|
||||
"fmt"
|
||||
"github.com/MickMake/GoUnify/Only"
|
||||
"os"
|
||||
@ -11,84 +12,6 @@ import (
|
||||
)
|
||||
|
||||
|
||||
const (
|
||||
PointId = "PointId" // Point id in the form p\d+ or \d+
|
||||
PointParentId = "PointParentId" // Associated parent of point.
|
||||
PointUpdateFreq = "PointUpdateFreq" // Point update frequency - Total, Yearly, Monthly, Day.
|
||||
PointValueType = "PointValueType" // Value type of point: energy, date, battery, temperature.
|
||||
PointIgnore = "PointIgnore" // Ignore this point.
|
||||
PointIgnoreIfNil = "PointIgnoreIfNil" // Ignore this point if a child is nil or empty.
|
||||
PointIgnoreIfNilFromChild = "PointIgnoreIfNilFromChild" // Ignore this point if a child is nil or empty.
|
||||
|
||||
PointAliasTo = "PointAliasTo" // Alias this point to another point.
|
||||
PointAliasFrom = "PointAliasFrom" // Alias this point from another point.
|
||||
|
||||
PointUnit = "PointUnit" // Units: Wh, kWh, C, h.
|
||||
PointUnitFrom = "PointUnitFrom" // Get PointUnit from another field structure.
|
||||
PointUnitFromParent = "PointUnitFromParent" // Get PointUnit from another parent field structure.
|
||||
|
||||
PointGroupName = "PointGroupName" // Point group name.
|
||||
PointGroupNameFrom = "PointGroupNameFrom" // Get PointGroupName from another field structure.
|
||||
|
||||
PointName = "PointName" // Human-readable name of point.
|
||||
PointNameFromChild = "PointNameFromChild" // Searches child for field value to use for naming when hitting a slice, (as opposed to using an index).
|
||||
PointNameFromParent = "PointNameFromParent" // Searches child for field value to use for naming when hitting a slice, (as opposed to using an index).
|
||||
PointNameDateFormat = "PointNameDateFormat" // Date format when using PointNameFrom, (if the field is a time.Time type).
|
||||
PointNameAppend = "PointNameAppend" // Append PointNameFrom instead of replace.
|
||||
|
||||
PointArrayFlatten = "PointArrayFlatten" // Flatten an array into a string. EG: ["one", "two", "three"]
|
||||
PointSplitOn = "PointSplitOn" // Split a point into an array separating by defined string.
|
||||
PointSplitOnType = "PointSplitOnType" // What valueTypes will be used for a split.
|
||||
PointIgnoreZero = "PointIgnoreZero" // Ignore arrays with zero size, (default true).
|
||||
|
||||
PointTimestampFrom = "PointTimestampFrom" // Pull timestamp from another field structure.
|
||||
|
||||
IsDataTable = "DataTable" // This entity is a data table - Will only traverse down one child.
|
||||
DataTableId = "DataTableId" // Table id, (defaults to Json tag).
|
||||
DataTableName = "DataTableName" // Table Name, (defaults to DataTableId).
|
||||
DataTableTitle = "DataTableTitle" // Table Title, (defaults to DataTableId in name format).
|
||||
DataTableMerge = "DataTableMerge" // Merge rows together - useful for when we use, for EG: []valueTypes.Float
|
||||
DataTableShowIndex = "DataTableShowIndex" // Show index on table.
|
||||
)
|
||||
|
||||
const (
|
||||
UpdateFreqInstant = "instant"
|
||||
UpdateFreq5Mins = "5mins"
|
||||
UpdateFreqBoot = "boot"
|
||||
UpdateFreqDay = "daily"
|
||||
UpdateFreqMonth = "monthly"
|
||||
UpdateFreqYear = "yearly"
|
||||
UpdateFreqTotal = "total"
|
||||
)
|
||||
|
||||
|
||||
type EndPointPath []string
|
||||
|
||||
func NewEndPointPath(path ...string) EndPointPath {
|
||||
var epp EndPointPath
|
||||
return epp.Append(path...)
|
||||
}
|
||||
|
||||
func (e *EndPointPath) Copy() EndPointPath {
|
||||
ret := make(EndPointPath, len(*e))
|
||||
copy(ret, *e)
|
||||
return ret
|
||||
}
|
||||
|
||||
func (e *EndPointPath) Append(path ...string) EndPointPath {
|
||||
ret := make(EndPointPath, len(*e))
|
||||
copy(ret, *e)
|
||||
for _, p := range path {
|
||||
ret = append(ret, p)
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
||||
func (e EndPointPath) String() string {
|
||||
return strings.Join(e, ".")
|
||||
}
|
||||
|
||||
|
||||
type DataStructure struct {
|
||||
Required bool
|
||||
Json string
|
||||
@ -129,6 +52,7 @@ type DataStructure struct {
|
||||
DataTableTitle string
|
||||
DataTableMerge bool
|
||||
DataTableShowIndex bool
|
||||
DataTableSortOn string
|
||||
|
||||
Value interface{}
|
||||
ValueType string
|
||||
@ -145,7 +69,7 @@ func (ds *DataStructure) Set(parent interface{}, current interface{}, fieldTo re
|
||||
|
||||
pointIgnoreIfNil := fieldTo.Tag.Get(PointIgnoreIfNil)
|
||||
if pointIgnoreIfNil != "" {
|
||||
ret := GetStringFrom(current, pointIgnoreIfNil)
|
||||
ret := reflection.GetStringFrom(current, pointIgnoreIfNil)
|
||||
if (ret == "") || (ret == "--") {
|
||||
ignore = true
|
||||
}
|
||||
@ -173,7 +97,7 @@ func (ds *DataStructure) Set(parent interface{}, current interface{}, fieldTo re
|
||||
// pointValueType = "NIL"
|
||||
// }
|
||||
|
||||
pointJson := getJsonTag(fieldTo)
|
||||
pointJson := reflection.GetJsonTag(fieldTo)
|
||||
pointId := fieldTo.Tag.Get(PointId)
|
||||
if pointId == "" {
|
||||
pointId = pointJson
|
||||
@ -183,22 +107,22 @@ func (ds *DataStructure) Set(parent interface{}, current interface{}, fieldTo re
|
||||
pointUnitFrom := fieldTo.Tag.Get(PointUnitFrom)
|
||||
pointUnitFromParent := fieldTo.Tag.Get(PointUnitFromParent)
|
||||
if pointUnitFrom != "" {
|
||||
pointUnit = GetStringFrom(current, pointUnitFrom)
|
||||
pointUnit = reflection.GetStringFrom(current, pointUnitFrom)
|
||||
}
|
||||
if pointUnitFromParent != "" {
|
||||
pointUnit = GetStringFrom(parent, pointUnitFromParent)
|
||||
pointUnit = reflection.GetStringFrom(parent, pointUnitFromParent)
|
||||
}
|
||||
|
||||
pointGroupName := fieldTo.Tag.Get(PointGroupName)
|
||||
pointGroupNameFrom := fieldTo.Tag.Get(PointGroupNameFrom)
|
||||
if pointGroupNameFrom != "" {
|
||||
pointGroupName = GetStringFrom(current, pointGroupNameFrom)
|
||||
pointGroupName = reflection.GetStringFrom(current, pointGroupNameFrom)
|
||||
}
|
||||
|
||||
pointTimestamp := time.Now()
|
||||
pointTimestampFrom := fieldTo.Tag.Get(PointTimestampFrom)
|
||||
if pointTimestampFrom != "" {
|
||||
pointTimestamp = GetTimestampFrom(current, pointTimestampFrom, valueTypes.DateTimeLayout)
|
||||
pointTimestamp = reflection.GetTimestampFrom(current, pointTimestampFrom, valueTypes.DateTimeLayout)
|
||||
}
|
||||
|
||||
var valueType string
|
||||
@ -264,16 +188,6 @@ func (ds *DataStructure) Set(parent interface{}, current interface{}, fieldTo re
|
||||
dataTableShowIndex = true
|
||||
}
|
||||
|
||||
dtn := fieldTo.Tag.Get(DataTableName)
|
||||
if dtn == "" {
|
||||
dtn = valueTypes.PointToName(pointId)
|
||||
}
|
||||
|
||||
did := fieldTo.Tag.Get(DataTableId)
|
||||
if did == "" {
|
||||
did = pointId
|
||||
}
|
||||
|
||||
*ds = DataStructure {
|
||||
Required: required,
|
||||
Json: pointJson,
|
||||
@ -307,12 +221,13 @@ func (ds *DataStructure) Set(parent interface{}, current interface{}, fieldTo re
|
||||
PointSplitOnType: fieldTo.Tag.Get(PointSplitOnType),
|
||||
PointIgnoreZero: pointIgnoreZero,
|
||||
|
||||
DataTable: dataTable,
|
||||
DataTableId: did,
|
||||
DataTableName: dtn,
|
||||
DataTableTitle: fieldTo.Tag.Get(DataTableTitle),
|
||||
DataTableMerge: dataTableMerge,
|
||||
DataTable: dataTable,
|
||||
DataTableId: fieldTo.Tag.Get(DataTableId),
|
||||
DataTableName: fieldTo.Tag.Get(DataTableName),
|
||||
DataTableTitle: fieldTo.Tag.Get(DataTableTitle),
|
||||
DataTableMerge: dataTableMerge,
|
||||
DataTableShowIndex: dataTableShowIndex,
|
||||
DataTableSortOn: fieldTo.Tag.Get(DataTableSortOn),
|
||||
|
||||
Value: fieldVo.Interface(),
|
||||
ValueType: valueType,
|
||||
@ -323,14 +238,6 @@ func (ds *DataStructure) Set(parent interface{}, current interface{}, fieldTo re
|
||||
return *ds
|
||||
}
|
||||
|
||||
func COMPARE(name EndPointPath, ref1 interface{}, ref2 interface{}) {
|
||||
t1 := fmt.Sprintf("%v", ref1)
|
||||
t2 := fmt.Sprintf("%v", ref2)
|
||||
if t1 != t2 {
|
||||
fmt.Printf("[%s] VALUE ERROR: '%s' != '%s'\n", name, t1, t2)
|
||||
}
|
||||
}
|
||||
|
||||
type DataStructures struct {
|
||||
DataMap map[string]DataStructure
|
||||
DataTables DataTables
|
||||
@ -338,7 +245,7 @@ type DataStructures struct {
|
||||
Debug bool
|
||||
}
|
||||
|
||||
func (dss *DataStructures) GetPointTags(Parent Reflect, Current Reflect, name EndPointPath) DataStructures {
|
||||
func (dss *DataStructures) GetPointTags(Parent *Reflect, Current *Reflect, name EndPointPath) DataStructures {
|
||||
|
||||
for range Only.Once {
|
||||
if Current.DataStructure.DataTable {
|
||||
@ -456,7 +363,7 @@ func (dss *DataStructures) Append(dsm DataStructures) {
|
||||
}
|
||||
}
|
||||
|
||||
func (dss *DataStructures) ProcessUnsupported(_ Reflect, Current Reflect, name EndPointPath) {
|
||||
func (dss *DataStructures) ProcessUnsupported(_ *Reflect, Current *Reflect, name EndPointPath) {
|
||||
for range Only.Once {
|
||||
if dss.ShowEmpty {
|
||||
dss.Add(Current.DataStructure)
|
||||
@ -466,7 +373,7 @@ func (dss *DataStructures) ProcessUnsupported(_ Reflect, Current Reflect, name E
|
||||
}
|
||||
}
|
||||
|
||||
func (dss *DataStructures) ProcessSlice(Parent Reflect, Current Reflect, name EndPointPath) {
|
||||
func (dss *DataStructures) ProcessSlice(Parent *Reflect, Current *Reflect, name EndPointPath) {
|
||||
for range Only.Once {
|
||||
// Handle slices here.
|
||||
if dss.ShowEmpty {
|
||||
@ -480,7 +387,7 @@ func (dss *DataStructures) ProcessSlice(Parent Reflect, Current Reflect, name En
|
||||
|
||||
for si := 0; si < Current.Length; si++ {
|
||||
var Child Reflect
|
||||
Child.SetByIndex(Parent, Current, si, name)
|
||||
Child.SetByIndex(*Parent, *Current, si, reflect.Value{}, name)
|
||||
if dss.Debug {
|
||||
_, _ = fmt.Fprintf(os.Stderr,"SetByIndex() Child: %s\n", Child)
|
||||
}
|
||||
@ -489,111 +396,101 @@ func (dss *DataStructures) ProcessSlice(Parent Reflect, Current Reflect, name En
|
||||
name2 = Current.PointNameFromChild(Child, name)
|
||||
}
|
||||
|
||||
if Child.Kind == reflect.Slice {
|
||||
if Child.IsUnknown() {
|
||||
dss.GetPointTags(Current, Child, name2)
|
||||
continue
|
||||
}
|
||||
|
||||
if dss.PointSplitOn(Current, Child, name2) {
|
||||
continue
|
||||
}
|
||||
|
||||
COMPARE(Child.DataStructure.Endpoint, Child.DataStructure.Value, Child.Interface)
|
||||
dss.Add(Child.DataStructure)
|
||||
continue
|
||||
}
|
||||
|
||||
if Child.IsUnknown() {
|
||||
dss.GetPointTags(Current, Child, name2)
|
||||
dss.GetPointTags(Current, &Child, name2)
|
||||
continue
|
||||
}
|
||||
|
||||
if dss.PointSplitOn(Current, &Child, name2) {
|
||||
continue
|
||||
}
|
||||
|
||||
dss.Add(Child.DataStructure)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (dss *DataStructures) ProcessStruct(Parent Reflect, Current Reflect, name EndPointPath) {
|
||||
func (dss *DataStructures) ProcessStruct(Parent *Reflect, Current *Reflect, name EndPointPath) {
|
||||
for range Only.Once {
|
||||
// Iterate over all available fields and read the tag value
|
||||
for si := 0; si < Current.Length; si++ {
|
||||
var Child Reflect
|
||||
Child.SetByIndex(Parent, Current, si, name)
|
||||
Child.SetByIndex(*Parent, *Current, si, reflect.Value{}, name)
|
||||
if dss.Debug {
|
||||
_, _ = fmt.Fprintf(os.Stderr,"SetByIndex() Child: %s\n", Child)
|
||||
}
|
||||
name2 := Child.DataStructure.Endpoint.Copy()
|
||||
if Current.DataStructure.PointNameFromChild != "" {
|
||||
name2 = Current.PointNameFromChild(Child, name)
|
||||
}
|
||||
|
||||
if !Child.IsExported {
|
||||
_, _ = fmt.Fprintf(os.Stderr, "WARNING: Field '%s' type not exported (%s): Type %s\n", Child.FieldName, name2, Child.Kind.String())
|
||||
continue
|
||||
}
|
||||
|
||||
if Child.Kind == reflect.Struct {
|
||||
if Child.IsUnknown() {
|
||||
dss.GetPointTags(Current, Child, name2)
|
||||
continue
|
||||
}
|
||||
|
||||
if dss.PointSplitOn(Current, Child, name2) {
|
||||
continue
|
||||
}
|
||||
|
||||
COMPARE(Child.DataStructure.Endpoint, Child.DataStructure.Value, Child.Interface)
|
||||
dss.Add(Child.DataStructure)
|
||||
if dss.GoStructOptions(Parent, Current, &Child, name) {
|
||||
continue
|
||||
}
|
||||
|
||||
if Child.IsUnknown() {
|
||||
dss.GetPointTags(Current, Child, name2)
|
||||
dss.GetPointTags(Current, &Child, name2)
|
||||
continue
|
||||
}
|
||||
COMPARE(Child.DataStructure.Endpoint, Child.DataStructure.Value, Child.Interface)
|
||||
|
||||
if dss.PointSplitOn(Current, &Child, name2) {
|
||||
continue
|
||||
}
|
||||
|
||||
// COMPARE(Child.DataStructure.Endpoint, Child.DataStructure.Value, Child.Interface)
|
||||
dss.Add(Child.DataStructure)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (dss *DataStructures) ProcessMap(Parent Reflect, Current Reflect, name EndPointPath) {
|
||||
func (dss *DataStructures) ProcessMap(Parent *Reflect, Current *Reflect, name EndPointPath) {
|
||||
for range Only.Once {
|
||||
for si := range Current.FieldVo.MapKeys() {
|
||||
for si, sm := range Current.FieldVo.MapKeys() {
|
||||
// @TODO - Implement pointNameFromChild / pointNameFromParent.
|
||||
// @TODO - Need to look at other types, besides known types.
|
||||
var Child Reflect
|
||||
Child.SetByIndex(Parent, Current, si, name)
|
||||
Child.SetByIndex(*Parent, *Current, si, sm, name)
|
||||
if dss.Debug {
|
||||
_, _ = fmt.Fprintf(os.Stderr,"SetByIndex() Child: %s\n", Child)
|
||||
}
|
||||
name2 := Child.DataStructure.Endpoint.Copy()
|
||||
if Current.DataStructure.PointNameFromChild != "" {
|
||||
name2 = Current.PointNameFromChild(Child, name)
|
||||
}
|
||||
|
||||
if Child.IsUnknown() {
|
||||
dss.GetPointTags(Current, Child, name2)
|
||||
dss.GetPointTags(Current, &Child, name2)
|
||||
continue
|
||||
}
|
||||
|
||||
if dss.PointSplitOn(Current, Child, name2) {
|
||||
if dss.PointSplitOn(Current, &Child, name2) {
|
||||
continue
|
||||
}
|
||||
|
||||
COMPARE(Child.DataStructure.Endpoint, Child.DataStructure.Value, Child.Interface)
|
||||
// COMPARE(Child.DataStructure.Endpoint, Child.DataStructure.Value, Child.Interface)
|
||||
dss.Add(Child.DataStructure)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (dss *DataStructures) PointNameAppend(_ Reflect, Current Reflect, name EndPointPath) []string {
|
||||
func (dss *DataStructures) PointNameAppend(_ *Reflect, Current *Reflect, name EndPointPath) EndPointPath {
|
||||
for range Only.Once {
|
||||
if Current.DataStructure.PointNameAppend == false {
|
||||
if len(name) == 0 {
|
||||
break
|
||||
}
|
||||
name = name[:len(name) - 1]
|
||||
name = name.PopLast()
|
||||
}
|
||||
}
|
||||
return name
|
||||
}
|
||||
|
||||
func (dss *DataStructures) PointArrayFlatten(_ Reflect, Current Reflect, name EndPointPath) bool {
|
||||
func (dss *DataStructures) PointArrayFlatten(_ *Reflect, Current *Reflect, name EndPointPath) bool {
|
||||
var yes bool
|
||||
for range Only.Once {
|
||||
if Current.DataStructure.PointArrayFlatten == true {
|
||||
@ -607,7 +504,7 @@ func (dss *DataStructures) PointArrayFlatten(_ Reflect, Current Reflect, name En
|
||||
return yes
|
||||
}
|
||||
|
||||
func (dss *DataStructures) PointIgnoreZero(_ Reflect, Current Reflect, _ EndPointPath) bool {
|
||||
func (dss *DataStructures) PointIgnoreZero(_ *Reflect, Current *Reflect, _ EndPointPath) bool {
|
||||
var yes bool
|
||||
for range Only.Once {
|
||||
if !Current.DataStructure.PointIgnoreZero {
|
||||
@ -626,7 +523,7 @@ func (dss *DataStructures) PointIgnoreZero(_ Reflect, Current Reflect, _ EndPoin
|
||||
return yes
|
||||
}
|
||||
|
||||
func (dss *DataStructures) PointIgnoreIfNilFromChild(Parent Reflect, Current Reflect, _ EndPointPath) bool {
|
||||
func (dss *DataStructures) PointIgnoreIfNilFromChild(Parent *Reflect, Current *Reflect, _ EndPointPath) bool {
|
||||
var yes bool
|
||||
for range Only.Once {
|
||||
if Parent.DataStructure.PointIgnoreIfNilFromChild == "" {
|
||||
@ -637,7 +534,7 @@ func (dss *DataStructures) PointIgnoreIfNilFromChild(Parent Reflect, Current Ref
|
||||
yes = false
|
||||
break
|
||||
}
|
||||
ret := GetStringFrom(Current.Interface, Parent.DataStructure.PointIgnoreIfNilFromChild)
|
||||
ret := reflection.GetStringFrom(Current.Interface, Parent.DataStructure.PointIgnoreIfNilFromChild)
|
||||
if ret == "" {
|
||||
yes = false
|
||||
break
|
||||
@ -647,7 +544,7 @@ func (dss *DataStructures) PointIgnoreIfNilFromChild(Parent Reflect, Current Ref
|
||||
return yes
|
||||
}
|
||||
|
||||
func (dss *DataStructures) PointSplitOn(_ Reflect, Current Reflect, _ EndPointPath) bool {
|
||||
func (dss *DataStructures) PointSplitOn(_ *Reflect, Current *Reflect, _ EndPointPath) bool {
|
||||
var yes bool
|
||||
for range Only.Once {
|
||||
if Current.DataStructure.PointSplitOn == "" {
|
||||
@ -668,213 +565,50 @@ func (dss *DataStructures) PointSplitOn(_ Reflect, Current Reflect, _ EndPointPa
|
||||
return yes
|
||||
}
|
||||
|
||||
|
||||
type DataTables struct {
|
||||
Map []*DataTable
|
||||
Merge bool
|
||||
Index bool
|
||||
}
|
||||
|
||||
func (dt *DataTables) Get() []*DataTable {
|
||||
return dt.Map
|
||||
}
|
||||
|
||||
|
||||
type DataTable struct {
|
||||
Reflect Reflect
|
||||
Name string
|
||||
Merge bool
|
||||
Index bool
|
||||
Headers []string
|
||||
Data [][]Reflect
|
||||
Debug bool
|
||||
}
|
||||
|
||||
func (dss *DataStructures) AddTable(ref Reflect) *DataTable {
|
||||
var ret *DataTable
|
||||
func (dss *DataStructures) GoStructOptions(Parent *Reflect, Current *Reflect, Child *Reflect, _ EndPointPath) bool {
|
||||
var yes bool
|
||||
for range Only.Once {
|
||||
if dss.DataTables.Map == nil {
|
||||
dss.DataTables.Map = []*DataTable{}
|
||||
}
|
||||
ret = &DataTable {
|
||||
Reflect: ref,
|
||||
Name: ref.DataStructure.DataTableId,
|
||||
Merge: ref.DataStructure.DataTableMerge,
|
||||
Index: ref.DataStructure.DataTableShowIndex,
|
||||
Headers: nil,
|
||||
Data: nil,
|
||||
}
|
||||
dss.DataTables.Map = append(dss.DataTables.Map, ret)
|
||||
if ref.DataStructure.DataTableMerge {
|
||||
dss.DataTables.Merge = true
|
||||
}
|
||||
if ref.DataStructure.DataTableShowIndex {
|
||||
dss.DataTables.Index = true
|
||||
}
|
||||
if dss.Debug {
|
||||
_, _ = fmt.Fprintf(os.Stderr, "DEBUG DataStructures.AddTable() %s - Kind:'%s' Type:'%s'\n",
|
||||
ref.DataStructure.Endpoint.String(), ref.DataStructure.ValueKind, ref.DataStructure.ValueType)
|
||||
}
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
||||
func (dt *DataTable) GetTable() DataTable {
|
||||
|
||||
for range Only.Once {
|
||||
if dt.Debug {
|
||||
_, _ = fmt.Fprintf(os.Stderr,"GetTable() Current[%s]: %s\n", dt.Reflect.DataStructure.DataTableId, dt.Reflect)
|
||||
}
|
||||
if !dt.Reflect.DataStructure.DataTable {
|
||||
if Child.FieldName != NameGoStruct {
|
||||
break
|
||||
}
|
||||
|
||||
if dt.Reflect.Kind == reflect.Pointer {
|
||||
// Special case:
|
||||
// We're going to change the pointer to a proper object reference.
|
||||
if dt.Reflect.IsNil {
|
||||
break
|
||||
}
|
||||
ref2 := dt.Reflect.ValueOf.Elem().Interface()
|
||||
if valueTypes.IsNil(ref2) {
|
||||
break
|
||||
}
|
||||
dt.Reflect.SetByFieldName(dt.Reflect.Interface, ref2, "")
|
||||
if dt.Reflect.IsNil {
|
||||
break
|
||||
}
|
||||
// @TODO - Need to check here if the parent is a slice.
|
||||
// If so - then "parent" is actually Parent.
|
||||
// If not - then "parent" is actually Current.
|
||||
|
||||
// DO NOT BREAK!
|
||||
// KEEP FIRST!
|
||||
if Child.DataStructure.DataTable {
|
||||
Parent.DataStructure.DataTable = Child.DataStructure.DataTable
|
||||
}
|
||||
if Child.DataStructure.DataTableMerge {
|
||||
Parent.DataStructure.DataTableMerge = Child.DataStructure.DataTableMerge
|
||||
}
|
||||
if Child.DataStructure.DataTableShowIndex {
|
||||
Parent.DataStructure.DataTableShowIndex = Child.DataStructure.DataTableShowIndex
|
||||
}
|
||||
if Child.DataStructure.DataTableId != "" {
|
||||
Parent.DataStructure.DataTableId = Child.DataStructure.DataTableId
|
||||
}
|
||||
if Child.DataStructure.DataTableName != "" {
|
||||
Parent.DataStructure.DataTableName = Child.DataStructure.DataTableName
|
||||
}
|
||||
if Child.DataStructure.DataTableTitle != "" {
|
||||
Parent.DataStructure.DataTableTitle = Child.DataStructure.DataTableTitle
|
||||
}
|
||||
if Child.DataStructure.DataTableSortOn != "" {
|
||||
Parent.DataStructure.DataTableSortOn = Child.DataStructure.DataTableSortOn
|
||||
}
|
||||
|
||||
if dt.Reflect.Kind == reflect.Slice {
|
||||
// Handle slices here.
|
||||
for row := 0; row < dt.Reflect.Length; row++ {
|
||||
var Child Reflect
|
||||
Child.SetByIndex(dt.Reflect, dt.Reflect, row, EndPointPath{})
|
||||
if dt.Debug {
|
||||
_, _ = fmt.Fprintf(os.Stderr,"SetByIndex() Child[%s]: %s\n", dt.Reflect.DataStructure.DataTableId, Child)
|
||||
}
|
||||
|
||||
if Child.IsKnown() {
|
||||
// We have a known value
|
||||
if row == 0 {
|
||||
dt.AddHeader(dt.Reflect)
|
||||
}
|
||||
dt.AddRow(Child)
|
||||
continue
|
||||
}
|
||||
|
||||
if Child.Kind == reflect.Struct {
|
||||
var refs []Reflect
|
||||
|
||||
for col := 0; col < Child.Length; col++ {
|
||||
var ChildStruct Reflect
|
||||
ChildStruct.SetByIndex(dt.Reflect, Child, col, EndPointPath{})
|
||||
if dt.Debug {
|
||||
_, _ = fmt.Fprintf(os.Stderr,"SetByIndex() Child: %s\n", ChildStruct)
|
||||
}
|
||||
|
||||
if !ChildStruct.IsExported {
|
||||
_, _ = fmt.Fprintf(os.Stderr, "WARNING: Field '%s' type not exported: Type %s\n", ChildStruct.FieldName, ChildStruct.Kind.String())
|
||||
continue
|
||||
}
|
||||
refs = append(refs, ChildStruct)
|
||||
}
|
||||
|
||||
if row == 0 {
|
||||
dt.AddHeader(refs...)
|
||||
} else {
|
||||
dt.AddRow(refs...)
|
||||
}
|
||||
}
|
||||
}
|
||||
break
|
||||
}
|
||||
|
||||
if dt.Reflect.Kind == reflect.Map {
|
||||
// Handle maps here.
|
||||
for row := range dt.Reflect.FieldVo.MapKeys() {
|
||||
var Child Reflect
|
||||
Child.SetByIndex(dt.Reflect, dt.Reflect, row, EndPointPath{})
|
||||
if dt.Debug {
|
||||
_, _ = fmt.Fprintf(os.Stderr,"SetByIndex() Child[%s]: %s\n", dt.Reflect.DataStructure.DataTableId, Child)
|
||||
}
|
||||
|
||||
if Child.IsKnown() {
|
||||
// We have a known value
|
||||
if row == 0 {
|
||||
dt.AddHeader(dt.Reflect)
|
||||
}
|
||||
dt.AddRow(Child)
|
||||
continue
|
||||
}
|
||||
|
||||
if dt.Reflect.Kind == reflect.Map {
|
||||
var refs []Reflect
|
||||
|
||||
for col := range dt.Reflect.FieldVo.MapKeys() {
|
||||
var ChildStruct Reflect
|
||||
ChildStruct.SetByIndex(dt.Reflect, Child, col, EndPointPath{})
|
||||
if dt.Debug {
|
||||
_, _ = fmt.Fprintf(os.Stderr,"SetByIndex() Child: %s\n", ChildStruct)
|
||||
}
|
||||
|
||||
if !ChildStruct.IsExported {
|
||||
_, _ = fmt.Fprintf(os.Stderr, "WARNING: Field '%s' type not exported: Type %s\n", ChildStruct.FieldName, ChildStruct.Kind.String())
|
||||
continue
|
||||
}
|
||||
refs = append(refs, ChildStruct)
|
||||
}
|
||||
|
||||
if row == 0 {
|
||||
dt.AddHeader(refs...)
|
||||
} else {
|
||||
dt.AddRow(refs...)
|
||||
}
|
||||
}
|
||||
}
|
||||
break
|
||||
}
|
||||
|
||||
_, _ = fmt.Fprintf(os.Stderr,"ERROR: Field '%s' type not supported (%s): Type %s\n",
|
||||
dt.Reflect.FieldName, dt.Reflect.DataStructure.DataTableId, dt.Reflect.Kind.String())
|
||||
dss.AddTable(Parent)
|
||||
yes = true
|
||||
}
|
||||
|
||||
return *dt
|
||||
return yes
|
||||
}
|
||||
|
||||
func (dt *DataTable) AddHeader(headers ...Reflect) {
|
||||
for range Only.Once {
|
||||
for _, header := range headers {
|
||||
name := valueTypes.PointToName(header.DataStructure.PointName)
|
||||
if header.DataStructure.PointUnit != "" {
|
||||
name += "\n" + header.DataStructure.PointUnit
|
||||
}
|
||||
dt.Headers = append(dt.Headers, name)
|
||||
}
|
||||
|
||||
func COMPARE(name EndPointPath, ref1 interface{}, ref2 interface{}) {
|
||||
t1 := fmt.Sprintf("%v", ref1)
|
||||
t2 := fmt.Sprintf("%v", ref2)
|
||||
if t1 != t2 {
|
||||
fmt.Printf("[%s] VALUE ERROR: '%s' != '%s'\n", name, t1, t2)
|
||||
}
|
||||
}
|
||||
|
||||
func (dt *DataTable) AddRow(refs ...Reflect) {
|
||||
for range Only.Once {
|
||||
if dt.Data == nil {
|
||||
dt.Data = make([][]Reflect, 0)
|
||||
}
|
||||
|
||||
var row []Reflect
|
||||
row = append(row, refs...)
|
||||
// for _, ref := range refs {
|
||||
// }
|
||||
dt.Data = append(dt.Data, row)
|
||||
}
|
||||
}
|
||||
|
||||
func (dt *DataTable) GetRow(row int) []Reflect {
|
||||
return dt.Data[row]
|
||||
}
|
||||
|
||||
func (dt *DataTable) Get() [][]Reflect {
|
||||
return dt.Data
|
||||
}
|
37
iSolarCloud/api/GoStruct/struct_epp.go
Normal file
37
iSolarCloud/api/GoStruct/struct_epp.go
Normal file
@ -0,0 +1,37 @@
|
||||
package GoStruct
|
||||
|
||||
import "strings"
|
||||
|
||||
|
||||
type EndPointPath []string
|
||||
|
||||
func NewEndPointPath(path ...string) EndPointPath {
|
||||
var epp EndPointPath
|
||||
return epp.Append(path...)
|
||||
}
|
||||
|
||||
func (e *EndPointPath) Copy() EndPointPath {
|
||||
ret := make(EndPointPath, len(*e))
|
||||
copy(ret, *e)
|
||||
return ret
|
||||
}
|
||||
|
||||
func (e *EndPointPath) Append(path ...string) EndPointPath {
|
||||
ret := make(EndPointPath, len(*e))
|
||||
copy(ret, *e)
|
||||
for _, p := range path {
|
||||
ret = append(ret, p)
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
||||
func (e *EndPointPath) PopLast() EndPointPath {
|
||||
if len(*e) == 0 {
|
||||
return *e
|
||||
}
|
||||
return (*e)[:len(*e) - 1]
|
||||
}
|
||||
|
||||
func (e EndPointPath) String() string {
|
||||
return strings.Join(e, ".")
|
||||
}
|
@ -1,14 +1,14 @@
|
||||
package apiReflect
|
||||
package GoStruct
|
||||
|
||||
import (
|
||||
"GoSungrow/Only"
|
||||
"GoSungrow/iSolarCloud/api/valueTypes"
|
||||
"crypto/md5"
|
||||
"GoSungrow/iSolarCloud/api/GoStruct/reflection"
|
||||
"GoSungrow/iSolarCloud/api/GoStruct/valueTypes"
|
||||
"errors"
|
||||
"fmt"
|
||||
"os"
|
||||
"reflect"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
|
||||
@ -124,7 +124,7 @@ func (r *Reflect) SetByFieldName(parent interface{}, current interface{}, name s
|
||||
}
|
||||
}
|
||||
|
||||
func (r *Reflect) SetByIndex(parent Reflect, current Reflect, index int, name EndPointPath) {
|
||||
func (r *Reflect) SetByIndex(parent Reflect, current Reflect, index int, indexName reflect.Value, name EndPointPath) {
|
||||
for range Only.Once {
|
||||
// Get child interface from parent.
|
||||
// pt := current.TypeOf
|
||||
@ -143,8 +143,9 @@ func (r *Reflect) SetByIndex(parent Reflect, current Reflect, index int, name En
|
||||
case reflect.Array:
|
||||
r.Interface = current.ValueOf.Index(index).Interface()
|
||||
case reflect.Map:
|
||||
mk := current.ValueOf.MapKeys()
|
||||
r.Interface = current.ValueOf.MapIndex(mk[index]).Interface()
|
||||
// mk := current.ValueOf.MapKeys()
|
||||
// r.Interface = current.ValueOf.MapIndex(mk[index]).Interface()
|
||||
r.Interface = current.ValueOf.MapIndex(indexName).Interface()
|
||||
}
|
||||
|
||||
r.Valid = true
|
||||
@ -192,7 +193,7 @@ func (r *Reflect) SetByIndex(parent Reflect, current Reflect, index int, name En
|
||||
r.FieldTo = reflect.StructField{}
|
||||
r.IsExported = true
|
||||
r.FieldVo = current.ValueOf.Index(index)
|
||||
r.FieldName = r.FieldVo.String()
|
||||
r.FieldName = current.FieldName // r.FieldVo.String()
|
||||
r.DataStructure = r.DataStructure.Set(parent.Interface, current.Interface, r.FieldTo, r.FieldVo)
|
||||
if r.Length == 0 {
|
||||
r.DataStructure.PointNameAppend = false
|
||||
@ -225,13 +226,18 @@ func (r *Reflect) SetByIndex(parent Reflect, current Reflect, index int, name En
|
||||
// r.IsExported = r.FieldTo.IsExported()
|
||||
r.FieldTo = reflect.StructField{}
|
||||
r.IsExported = true
|
||||
mk := current.ValueOf.MapKeys()
|
||||
r.FieldVo = current.ValueOf.MapIndex(mk[index])
|
||||
r.FieldName = mk[index].String()
|
||||
// mk := current.ValueOf.MapKeys()
|
||||
// r.FieldVo = current.ValueOf.MapIndex(mk[index])
|
||||
r.FieldVo = current.ValueOf.MapIndex(indexName)
|
||||
r.FieldName = current.FieldName // mk[index].String()
|
||||
|
||||
r.DataStructure = r.DataStructure.Set(parent.Interface, current.Interface, r.FieldTo, r.FieldVo)
|
||||
r.DataStructure.Json = mk[index].String()
|
||||
r.DataStructure.PointId = mk[index].String()
|
||||
// r.DataStructure.Json = current.ValueOf.MapIndex(indexName).String()
|
||||
// r.DataStructure.PointId = current.ValueOf.MapIndex(indexName).String()
|
||||
r.DataStructure.Json = indexName.String()
|
||||
r.DataStructure.PointId = indexName.String()
|
||||
// r.DataStructure.Json = r.FieldVo.String()
|
||||
// r.DataStructure.PointId = r.FieldVo.String()
|
||||
|
||||
r.DataStructure.Endpoint = name.Copy()
|
||||
r.DataStructure.Endpoint = append(r.DataStructure.Endpoint, r.DataStructure.PointId)
|
||||
@ -265,7 +271,7 @@ func (r *Reflect) setPointName(parent Reflect, current Reflect, name []string, i
|
||||
switch {
|
||||
case r.DataStructure.PointNameFromChild != "":
|
||||
// PointNameFromChild - In this case points to a field within a CHILD struct.
|
||||
pn = GetPointNameFrom(current.Interface, r.DataStructure.PointNameFromChild, intSize, r.DataStructure.PointNameDateFormat)
|
||||
pn = reflection.GetPointNameFrom(current.Interface, r.DataStructure.PointNameFromChild, intSize, r.DataStructure.PointNameDateFormat)
|
||||
if r.DataStructure.PointNameAppend == false {
|
||||
name = append(name[:len(name) - 1], pn)
|
||||
} else {
|
||||
@ -274,7 +280,7 @@ func (r *Reflect) setPointName(parent Reflect, current Reflect, name []string, i
|
||||
|
||||
case r.DataStructure.PointNameFromParent != "":
|
||||
// PointNameFromChild - In this case points to a field within a CHILD struct.
|
||||
pn = GetPointNameFrom(parent.Interface, r.DataStructure.PointNameFromParent, intSize, r.DataStructure.PointNameDateFormat)
|
||||
pn = reflection.GetPointNameFrom(parent.Interface, r.DataStructure.PointNameFromParent, intSize, r.DataStructure.PointNameDateFormat)
|
||||
if r.DataStructure.PointNameAppend == false {
|
||||
name = append(name[:len(name) - 1], pn)
|
||||
} else {
|
||||
@ -297,7 +303,7 @@ func (r *Reflect) PointNameFromChild(child Reflect, name EndPointPath) []string
|
||||
for range Only.Once {
|
||||
if r.DataStructure.PointNameFromChild != "" {
|
||||
// PointNameFromChild - In this case points to a field within a CHILD struct.
|
||||
pn := GetPointNameFrom(child.Interface, r.DataStructure.PointNameFromChild, 0, r.DataStructure.PointNameDateFormat)
|
||||
pn := reflection.GetPointNameFrom(child.Interface, r.DataStructure.PointNameFromChild, 0, r.DataStructure.PointNameDateFormat)
|
||||
name = append(name, pn)
|
||||
}
|
||||
}
|
||||
@ -305,6 +311,98 @@ func (r *Reflect) PointNameFromChild(child Reflect, name EndPointPath) []string
|
||||
}
|
||||
|
||||
|
||||
func FindStart(fieldName string, Parent Reflect, Current Reflect, name EndPointPath) *Reflect {
|
||||
var ret Reflect
|
||||
|
||||
for range Only.Once {
|
||||
if Current.Kind == reflect.Pointer {
|
||||
// Special case:
|
||||
// We're going to change the pointer to a proper object reference.
|
||||
if Current.IsNil {
|
||||
break
|
||||
}
|
||||
ref2 := Current.ValueOf.Elem().Interface()
|
||||
if valueTypes.IsNil(ref2) {
|
||||
break
|
||||
}
|
||||
Current.SetByFieldName(Current.Interface, ref2, "")
|
||||
if Current.IsNil {
|
||||
break
|
||||
}
|
||||
// DO NOT BREAK!
|
||||
// KEEP FIRST!
|
||||
}
|
||||
|
||||
if Current.Kind == reflect.Struct {
|
||||
// Iterate over all available fields and read the tag value
|
||||
for si := 0; si < Current.Length; si++ {
|
||||
var Child Reflect
|
||||
Child.SetByIndex(Parent, Current, si, reflect.Value{}, name)
|
||||
if Child.FieldName == fieldName {
|
||||
// if !Child.DataStructure.PointNameAppend {
|
||||
// Child.DataStructure.Endpoint = Child.DataStructure.Endpoint.PopLast()
|
||||
// }
|
||||
name = name.Append(Child.DataStructure.PointId)
|
||||
ret = Child
|
||||
break
|
||||
}
|
||||
|
||||
if Child.Kind != reflect.Struct {
|
||||
continue
|
||||
}
|
||||
|
||||
if Child.IsKnown() {
|
||||
continue
|
||||
}
|
||||
|
||||
Child = *FindStart(fieldName, Current, Child, name)
|
||||
// if Child.FieldName == fieldName {
|
||||
// name = name.Append(Child.DataStructure.PointId)
|
||||
// ret = Child
|
||||
// break
|
||||
// }
|
||||
}
|
||||
break
|
||||
}
|
||||
|
||||
if Current.Kind == reflect.Slice {
|
||||
// Iterate over all available fields and read the tag value
|
||||
for si := 0; si < Current.Length; si++ {
|
||||
var Child Reflect
|
||||
Child.SetByIndex(Parent, Current, si, reflect.Value{}, name)
|
||||
if Child.FieldName == fieldName {
|
||||
// if !Child.DataStructure.PointNameAppend {
|
||||
// Child.DataStructure.Endpoint = Child.DataStructure.Endpoint.PopLast()
|
||||
// }
|
||||
name = name.Append(Child.DataStructure.PointId)
|
||||
ret = Child
|
||||
break
|
||||
}
|
||||
|
||||
if Child.Kind != reflect.Slice {
|
||||
continue
|
||||
}
|
||||
|
||||
if Child.IsKnown() {
|
||||
continue
|
||||
}
|
||||
|
||||
Child = *FindStart(fieldName, Current, Child, name)
|
||||
// if Child.FieldName == fieldName {
|
||||
// name = name.Append(Child.DataStructure.PointId)
|
||||
// ret = Child
|
||||
// break
|
||||
// }
|
||||
}
|
||||
break
|
||||
}
|
||||
|
||||
_, _ = fmt.Fprintf(os.Stderr,"ERROR: Field '%s' type not supported: Type %s\n", Current.FieldName, Current.Kind.String())
|
||||
}
|
||||
|
||||
return &ret
|
||||
}
|
||||
|
||||
func GetStructFields(ref interface{}) map[string]string {
|
||||
ret := make(map[string]string)
|
||||
|
||||
@ -322,7 +420,7 @@ func GetStructFields(ref interface{}) map[string]string {
|
||||
// Iterate over all available fields and read the tag value
|
||||
for i := 0; i < Ref.Length; i++ {
|
||||
var Child Reflect
|
||||
Child.SetByIndex(Ref, Ref, i, EndPointPath{})
|
||||
Child.SetByIndex(Ref, Ref, i, reflect.Value{}, EndPointPath{})
|
||||
|
||||
if !Child.IsExported {
|
||||
continue
|
||||
@ -354,7 +452,7 @@ func GetStructFieldsAsArray(ref interface{}) []string {
|
||||
// Iterate over all available fields and read the tag value
|
||||
for i := 0; i < Ref.Length; i++ {
|
||||
var Child Reflect
|
||||
Child.SetByIndex(Ref, Ref, i, EndPointPath{})
|
||||
Child.SetByIndex(Ref, Ref, i, reflect.Value{}, EndPointPath{})
|
||||
|
||||
if !Child.IsExported {
|
||||
continue
|
||||
@ -385,7 +483,7 @@ func GetStructValuesAsArray(ref interface{}) []string {
|
||||
// Iterate over all available fields and read the tag value
|
||||
for i := 0; i < Ref.Length; i++ {
|
||||
var Child Reflect
|
||||
Child.SetByIndex(Ref, Ref, i, EndPointPath{})
|
||||
Child.SetByIndex(Ref, Ref, i, reflect.Value{}, EndPointPath{})
|
||||
|
||||
if !Child.IsExported {
|
||||
continue
|
||||
@ -399,238 +497,44 @@ func GetStructValuesAsArray(ref interface{}) []string {
|
||||
return ret
|
||||
}
|
||||
|
||||
func GetStringFrom(ref interface{}, name string) string {
|
||||
var ret string
|
||||
|
||||
type Required []string
|
||||
|
||||
func (r *Required) IsRequired(field string) bool {
|
||||
var ok bool
|
||||
for _, f := range *r {
|
||||
if f == field {
|
||||
ok = true
|
||||
}
|
||||
}
|
||||
return ok
|
||||
}
|
||||
|
||||
func (r *Required) IsNotRequired(field string) bool {
|
||||
return !r.IsRequired(field)
|
||||
}
|
||||
|
||||
// GetOptionsRequired Get field options within the structure that are required.
|
||||
func GetOptionsRequired(ref interface{}) Required {
|
||||
var ret []string
|
||||
|
||||
for range Only.Once {
|
||||
vo := reflect.ValueOf(ref)
|
||||
t := reflect.TypeOf(ref)
|
||||
for i := 0; i < t.NumField(); i++ {
|
||||
field := t.Field(i)
|
||||
required := field.Tag.Get("required")
|
||||
if required == "" {
|
||||
continue
|
||||
}
|
||||
|
||||
switch vo.Kind() {
|
||||
case reflect.Struct:
|
||||
// Iterate over all available fields, looking for the field name.
|
||||
for i := 0; i < vo.NumField(); i++ {
|
||||
if vo.Type().Field(i).Name == name {
|
||||
ret = valueTypes.AnyToValueString(vo.Field(i).Interface(), 0, "")
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
case reflect.Map:
|
||||
// Iterate over all available fields, looking for the field name.
|
||||
for _, key := range vo.MapKeys() {
|
||||
if key.String() == name {
|
||||
ret = valueTypes.AnyToValueString(vo.MapIndex(key).Interface(), 0, "")
|
||||
break
|
||||
}
|
||||
}
|
||||
ret = append(ret, field.Name)
|
||||
}
|
||||
}
|
||||
|
||||
return ret
|
||||
}
|
||||
|
||||
func GetTimestampFrom(ref interface{}, name string, dateFormat string) time.Time {
|
||||
var ret time.Time
|
||||
for range Only.Once {
|
||||
if dateFormat == "" {
|
||||
dateFormat = valueTypes.DateTimeAltLayout
|
||||
}
|
||||
vo := reflect.ValueOf(ref)
|
||||
|
||||
switch vo.Kind() {
|
||||
case reflect.Struct:
|
||||
// Iterate over all available fields, looking for the field name.
|
||||
for i := 0; i < vo.NumField(); i++ {
|
||||
if vo.Type().Field(i).Name == name {
|
||||
v := fmt.Sprintf("%v", vo.Field(i).Interface())
|
||||
ret = valueTypes.SetDateTimeString(v).Time
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
case reflect.Map:
|
||||
// Iterate over all available fields, looking for the field name.
|
||||
for _, key := range vo.MapKeys() {
|
||||
if key.String() == name {
|
||||
v := fmt.Sprintf("%v", vo.MapIndex(key).Interface())
|
||||
ret = valueTypes.SetDateTimeString(v).Time
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ret
|
||||
}
|
||||
|
||||
func GetPointNameFrom(ref interface{}, name string, intSize int, dateFormat string) string {
|
||||
var ret string
|
||||
for range Only.Once {
|
||||
if dateFormat == "" {
|
||||
dateFormat = valueTypes.DateTimeAltLayout
|
||||
}
|
||||
vo := reflect.ValueOf(ref)
|
||||
|
||||
var ra []string
|
||||
switch vo.Kind() {
|
||||
case reflect.Struct:
|
||||
for _, pnf := range strings.Split(name, ".") {
|
||||
// Iterate over all available fields, looking for the field name.
|
||||
for i := 0; i < vo.NumField(); i++ {
|
||||
fn := vo.Type().Field(i).Name
|
||||
if fn == pnf {
|
||||
ra = append(ra, valueTypes.AnyToValueString(vo.Field(i).Interface(), intSize, dateFormat))
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
case reflect.Map:
|
||||
for _, pnf := range strings.Split(name, ".") {
|
||||
// Iterate over all available keys, looking for the key name.
|
||||
for _, key := range vo.MapKeys() {
|
||||
if key.String() == pnf {
|
||||
ra = append(ra, valueTypes.AnyToValueString(vo.MapIndex(key).Interface(), intSize, dateFormat))
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
ret = strings.Join(ra, ".")
|
||||
}
|
||||
|
||||
return ret
|
||||
}
|
||||
|
||||
func getJsonTag(fieldTo reflect.StructField) string {
|
||||
var ret string
|
||||
|
||||
for range Only.Once {
|
||||
ret = fieldTo.Tag.Get("json")
|
||||
ret = strings.ReplaceAll(ret, "omitempty", "")
|
||||
ret = strings.TrimSuffix(ret, ",")
|
||||
}
|
||||
|
||||
return ret
|
||||
}
|
||||
|
||||
|
||||
// GetArea Return an Area name if we are given an Area or EndPoint struct.
|
||||
func GetArea(trim string, v interface{}) string {
|
||||
var ret string
|
||||
for range Only.Once {
|
||||
if v == nil {
|
||||
break
|
||||
}
|
||||
|
||||
val := reflect.ValueOf(v)
|
||||
ret1 := val.Type().PkgPath()
|
||||
ret1 = strings.TrimPrefix(ret1, trim)
|
||||
ret2 := val.Type().Name()
|
||||
|
||||
if ret2 == "Area" {
|
||||
s := strings.Split(ret1, "/")
|
||||
ret = s[len(s)-1]
|
||||
break
|
||||
}
|
||||
|
||||
if ret2 == "EndPoint" {
|
||||
s := strings.Split(ret1, "/")
|
||||
ret = s[len(s)-2]
|
||||
break
|
||||
}
|
||||
|
||||
ret = ret1
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
||||
// GetName Return an endpoint name if we are given an Area or EndPoint struct.
|
||||
func GetName(trim string, v interface{}) string {
|
||||
var ret string
|
||||
for range Only.Once {
|
||||
val := reflect.ValueOf(v)
|
||||
ret1 := val.Type().PkgPath()
|
||||
ret1 = strings.TrimPrefix(ret1, trim)
|
||||
ret2 := val.Type().Name()
|
||||
|
||||
if ret2 == "Area" {
|
||||
s := strings.Split(ret1, "/")
|
||||
ret = s[len(s)-2]
|
||||
break
|
||||
}
|
||||
|
||||
if ret2 == "EndPoint" {
|
||||
s := strings.Split(ret1, "/")
|
||||
ret = s[len(s)-1]
|
||||
break
|
||||
}
|
||||
|
||||
ret = ret1
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
||||
func GetType(v interface{}) string {
|
||||
return reflect.ValueOf(v).Type().Name()
|
||||
}
|
||||
|
||||
func GetPkgType(v interface{}) string {
|
||||
return reflect.ValueOf(v).Type().String()
|
||||
}
|
||||
|
||||
func GetStructName(v interface{}) (string, string) {
|
||||
var area string
|
||||
var endpoint string
|
||||
for range Only.Once {
|
||||
val := reflect.ValueOf(v)
|
||||
// ret = val.Type().Name() // Returns structure, (EndPoint name).
|
||||
// ret = val.Type().PkgPath() // Returns structure path.
|
||||
// ret = val.Type().String() // Returns
|
||||
|
||||
// @TODO - Need to check for pointers to struct
|
||||
// if t := reflect.TypeOf(ref); t.Kind() == reflect.Ptr {
|
||||
// ret = strings.ToLower(t.Elem().Name())
|
||||
// } else {
|
||||
// ret = strings.ToLower(t.Name())
|
||||
// }
|
||||
|
||||
s := strings.Split(val.Type().String(), ".")
|
||||
if len(s) < 2 {
|
||||
break
|
||||
}
|
||||
area = s[0]
|
||||
endpoint = s[1]
|
||||
}
|
||||
return area, endpoint
|
||||
}
|
||||
|
||||
func DoTypesMatch(a interface{}, b interface{}) error {
|
||||
var err error
|
||||
for range Only.Once {
|
||||
aName := GetType(a)
|
||||
bName := GetType(b)
|
||||
if aName == bName {
|
||||
break
|
||||
}
|
||||
err = errors.New(fmt.Sprintf("interface '%s' doesn't match '%s'", aName, bName))
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
func DoPkgTypesMatch(a interface{}, b interface{}) error {
|
||||
var err error
|
||||
for range Only.Once {
|
||||
aName := GetPkgType(a)
|
||||
bName := GetPkgType(b)
|
||||
if aName == bName {
|
||||
break
|
||||
}
|
||||
err = errors.New(fmt.Sprintf("interface '%s' doesn't match '%s'", aName, bName))
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
// VerifyOptionsRequired Verify fields within the structure that are required.
|
||||
// VerifyOptionsRequired Verify fields within the structure are required.
|
||||
func VerifyOptionsRequired(ref interface{}) error {
|
||||
var err error
|
||||
|
||||
@ -661,112 +565,3 @@ func VerifyOptionsRequired(ref interface{}) error {
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
func HelpOptions(ref interface{}) string {
|
||||
var ret string
|
||||
|
||||
for range Only.Once {
|
||||
t := reflect.TypeOf(ref)
|
||||
for i := 0; i < t.NumField(); i++ {
|
||||
field := t.Field(i)
|
||||
required := field.Tag.Get("required")
|
||||
if required == "" {
|
||||
ret += fmt.Sprintf("%s: optional\n", field.Name)
|
||||
continue
|
||||
}
|
||||
|
||||
ret += fmt.Sprintf("%s: required\n", field.Name)
|
||||
}
|
||||
}
|
||||
|
||||
return ret
|
||||
}
|
||||
|
||||
func FindRequestData(ref interface{}) string {
|
||||
var ret string
|
||||
|
||||
for range Only.Once {
|
||||
vo := reflect.ValueOf(ref)
|
||||
to := reflect.TypeOf(ref)
|
||||
|
||||
// Iterate over all available fields and read the tag value
|
||||
for i := 0; i < vo.NumField(); i++ {
|
||||
fieldTo := to.Field(i)
|
||||
// required := fieldTo.Tag.GetByJson("required")
|
||||
fmt.Printf(">%s\t", fieldTo.Name)
|
||||
|
||||
fieldVo := vo.Field(i)
|
||||
|
||||
fmt.Printf(">%s\n", fieldVo.String())
|
||||
value := fmt.Sprintf("%v", fieldVo.Interface())
|
||||
if value == "" {
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ret
|
||||
}
|
||||
|
||||
func GetRequestString(ref interface{}) string {
|
||||
var ret string
|
||||
|
||||
for range Only.Once {
|
||||
vo := reflect.ValueOf(ref)
|
||||
// Iterate over all available fields and read the tag value
|
||||
for i := 0; i < vo.NumField(); i++ {
|
||||
fieldVo := vo.Field(i)
|
||||
ret += fmt.Sprintf("-%v", fieldVo.Interface())
|
||||
}
|
||||
}
|
||||
|
||||
return ret
|
||||
}
|
||||
|
||||
func GetFingerprint(ref interface{}) string {
|
||||
var ret string
|
||||
|
||||
for range Only.Once {
|
||||
// h := hash(GetRequestString(ref))
|
||||
h := md5.Sum([]byte(GetRequestString(ref)))
|
||||
ret = fmt.Sprintf("%x", h)
|
||||
}
|
||||
|
||||
return ret
|
||||
}
|
||||
|
||||
|
||||
type Required []string
|
||||
|
||||
func (r *Required) IsRequired(field string) bool {
|
||||
var ok bool
|
||||
for _, f := range *r {
|
||||
if f == field {
|
||||
ok = true
|
||||
}
|
||||
}
|
||||
return ok
|
||||
}
|
||||
|
||||
func (r *Required) IsNotRequired(field string) bool {
|
||||
return !r.IsRequired(field)
|
||||
}
|
||||
|
||||
func GetOptionsRequired(ref interface{}) Required {
|
||||
var ret []string
|
||||
|
||||
for range Only.Once {
|
||||
t := reflect.TypeOf(ref)
|
||||
for i := 0; i < t.NumField(); i++ {
|
||||
field := t.Field(i)
|
||||
required := field.Tag.Get("required")
|
||||
if required == "" {
|
||||
continue
|
||||
}
|
||||
|
||||
ret = append(ret, field.Name)
|
||||
}
|
||||
}
|
||||
|
||||
return ret
|
||||
}
|
522
iSolarCloud/api/GoStruct/struct_table.go
Normal file
522
iSolarCloud/api/GoStruct/struct_table.go
Normal file
@ -0,0 +1,522 @@
|
||||
package GoStruct
|
||||
|
||||
import (
|
||||
"GoSungrow/iSolarCloud/api/GoStruct/output"
|
||||
"GoSungrow/iSolarCloud/api/GoStruct/valueTypes"
|
||||
"fmt"
|
||||
"github.com/MickMake/GoUnify/Only"
|
||||
"os"
|
||||
"reflect"
|
||||
)
|
||||
|
||||
|
||||
type DataTables struct {
|
||||
Map []*DataTable
|
||||
Merge bool
|
||||
Index bool
|
||||
}
|
||||
|
||||
func (dts *DataTables) Get() []*DataTable {
|
||||
// for index, val := range dt.Map {
|
||||
// val.Reflect.String()
|
||||
// }
|
||||
return dts.Map
|
||||
}
|
||||
|
||||
func (dts *DataTables) GetTables(timestamp valueTypes.DateTime, parentDeviceId string) output.Tables {
|
||||
ret := make(output.Tables)
|
||||
for range Only.Once {
|
||||
for k, v := range dts.GetDataTables() {
|
||||
ret[k] = v
|
||||
}
|
||||
for k, v := range dts.GetDataMergedTables(timestamp, parentDeviceId) {
|
||||
ret[k] = v
|
||||
}
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
||||
func (dts *DataTables) GetDataMergedTables(timestamp valueTypes.DateTime, parentDeviceId string) output.Tables {
|
||||
ret := make(output.Tables)
|
||||
for range Only.Once {
|
||||
if !dts.Merge {
|
||||
break
|
||||
}
|
||||
|
||||
var data [][]interface{}
|
||||
var headers []string
|
||||
|
||||
if dts.Index {
|
||||
headers = append(headers, "Date/Time", "Index")
|
||||
}
|
||||
|
||||
// var names []string
|
||||
var name string
|
||||
for _, f := range dts.Get() {
|
||||
if f == nil {
|
||||
continue
|
||||
}
|
||||
if !f.Reflect.DataStructure.DataTable {
|
||||
continue
|
||||
}
|
||||
|
||||
// names = append(names, f.Name)
|
||||
|
||||
dt := f.GetTable()
|
||||
for index := range dt.Headers {
|
||||
headers = append(headers, dt.Headers[index])
|
||||
}
|
||||
name = dt.EndPoint.String()
|
||||
fmt.Printf("Name:%s\n", name)
|
||||
for rowIndex := range dt.Data {
|
||||
if data == nil {
|
||||
data = make([][]interface{}, 0)
|
||||
}
|
||||
for _, col := range dt.Data[rowIndex] {
|
||||
if col.DataStructure.PointNameDateFormat == "" {
|
||||
col.DataStructure.PointNameDateFormat = valueTypes.DateTimeLayout
|
||||
}
|
||||
value, _, _ := valueTypes.AnyToUnitValue(col.DataStructure.Value, col.DataStructure.PointUnit,
|
||||
col.DataStructure.PointValueType, col.DataStructure.PointNameDateFormat)
|
||||
|
||||
if (len(data) - 1) < rowIndex {
|
||||
var d []interface{}
|
||||
d = append(d, value[0].String())
|
||||
data = append(data, d)
|
||||
continue
|
||||
}
|
||||
// data[rowIndex] = append(data[rowIndex], uvs[0].String())
|
||||
data[rowIndex] = append(data[rowIndex], value[0].String())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if dts.Index {
|
||||
for i := range data {
|
||||
var t []interface{}
|
||||
t = append(t, timestamp.String(), i)
|
||||
data[i] = append(t, data[i]...)
|
||||
}
|
||||
}
|
||||
|
||||
table := output.NewTable(headers...)
|
||||
for i := range data {
|
||||
_ = table.AddRow(data[i]...)
|
||||
}
|
||||
// _ = table.SetHeader(headers...)
|
||||
table.SetTitle("Table %s-%s - (%s)", name, parentDeviceId)
|
||||
table.SetFilePrefix("%s-%s-%s", name, parentDeviceId)
|
||||
table.SetGraphFilter("")
|
||||
ret[name] = table
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
||||
func (dts *DataTables) GetDataTables() output.Tables {
|
||||
ret := make(output.Tables)
|
||||
for range Only.Once {
|
||||
if dts.Merge {
|
||||
break
|
||||
}
|
||||
|
||||
for _, f := range dts.Map {
|
||||
if !f.Reflect.DataStructure.DataTable {
|
||||
continue
|
||||
}
|
||||
|
||||
dt := f.GetTable()
|
||||
table := output.NewTable(dt.Headers...)
|
||||
for rowIndex := range dt.Data {
|
||||
// fmt.Printf("ROW[%d] - %v\n", rowIndex, dt.Data[rowIndex])
|
||||
var data []interface{}
|
||||
for _, col := range dt.Data[rowIndex] {
|
||||
// fmt.Printf("\tCOL[%d][%d] - %s - %s - %v\n", rowIndex, colIndex,
|
||||
// dt.Data[rowIndex][colIndex].FieldName,
|
||||
// dt.Data[rowIndex][colIndex].DataStructure.PointId,
|
||||
// dt.Data[rowIndex][colIndex].DataStructure.Value,
|
||||
// )
|
||||
if col.DataStructure.PointNameDateFormat == "" {
|
||||
col.DataStructure.PointNameDateFormat = valueTypes.DateTimeLayout
|
||||
}
|
||||
value, _, _ := valueTypes.AnyToUnitValue(col.DataStructure.Value, col.DataStructure.PointUnit,
|
||||
col.DataStructure.PointValueType, col.DataStructure.PointNameDateFormat)
|
||||
|
||||
data = append(data, value[0].String())
|
||||
}
|
||||
_ = table.AddRow(data...)
|
||||
}
|
||||
title := dt.Reflect.DataStructure.DataTableTitle
|
||||
if title == "" {
|
||||
title = dt.Reflect.DataStructure.DataTableName
|
||||
}
|
||||
if title == "" {
|
||||
title = dt.Reflect.DataStructure.DataTableId
|
||||
}
|
||||
|
||||
table.SetTitle("Data table %s - %s - %s", dt.Name, dt.EndPoint.String(), title)
|
||||
table.SetFilePrefix("%s-%s", dt.EndPoint.String(), dt.Reflect.DataStructure.DataTableId)
|
||||
table.SetGraphFilter("")
|
||||
table.Sort(dt.SortOn)
|
||||
ret[dt.Reflect.DataStructure.DataTableId] = table
|
||||
}
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
||||
|
||||
type DataTable struct {
|
||||
Reflect *Reflect
|
||||
Name string
|
||||
EndPoint EndPointPath
|
||||
SortOn string
|
||||
Headers []string
|
||||
Data [][]*Reflect
|
||||
Debug bool
|
||||
}
|
||||
|
||||
func (dss *DataStructures) AddTable(ref *Reflect) *DataTable {
|
||||
var ret *DataTable
|
||||
for range Only.Once {
|
||||
if ref.FieldName == NameGoStruct {
|
||||
break
|
||||
}
|
||||
|
||||
if dss.DataTables.Map == nil {
|
||||
dss.DataTables.Map = []*DataTable{}
|
||||
}
|
||||
ret = &DataTable {
|
||||
Reflect: ref,
|
||||
Name: ref.DataStructure.DataTableId,
|
||||
EndPoint: ref.DataStructure.Endpoint,
|
||||
SortOn: ref.DataStructure.DataTableSortOn,
|
||||
Headers: nil,
|
||||
Data: nil,
|
||||
}
|
||||
dss.DataTables.Map = append(dss.DataTables.Map, ret)
|
||||
// dss.DataTables.SortOn = ref.DataStructure.DataTableSortOn
|
||||
dss.DataTables.Merge = ref.DataStructure.DataTableMerge
|
||||
dss.DataTables.Index = ref.DataStructure.DataTableShowIndex
|
||||
if dss.Debug {
|
||||
_, _ = fmt.Fprintf(os.Stderr, "DEBUG DataStructures.AddTable() %s - Kind:'%s' Type:'%s'\n",
|
||||
ref.DataStructure.Endpoint.String(), ref.DataStructure.ValueKind, ref.DataStructure.ValueType)
|
||||
}
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
||||
func (dt *DataTable) GetTable() DataTable {
|
||||
|
||||
for range Only.Once {
|
||||
if dt.Debug {
|
||||
_, _ = fmt.Fprintf(os.Stderr,"GetTable() Current[%s]: %s\n", dt.Reflect.DataStructure.DataTableId, dt.Reflect)
|
||||
}
|
||||
if !dt.Reflect.DataStructure.DataTable {
|
||||
break
|
||||
}
|
||||
|
||||
if dt.Reflect.Kind == reflect.Pointer {
|
||||
// Special case:
|
||||
// We're going to change the pointer to a proper object reference.
|
||||
if dt.Reflect.IsNil {
|
||||
break
|
||||
}
|
||||
ref2 := dt.Reflect.ValueOf.Elem().Interface()
|
||||
if valueTypes.IsNil(ref2) {
|
||||
break
|
||||
}
|
||||
dt.Reflect.SetByFieldName(dt.Reflect.Interface, ref2, "")
|
||||
if dt.Reflect.IsNil {
|
||||
break
|
||||
}
|
||||
// DO NOT BREAK!
|
||||
// KEEP FIRST!
|
||||
}
|
||||
|
||||
if dt.Reflect.Kind == reflect.Struct {
|
||||
// Handle slices here.
|
||||
for row := 0; row < dt.Reflect.Length; row++ {
|
||||
var Child Reflect
|
||||
Child.SetByIndex(*dt.Reflect, *dt.Reflect, row, reflect.Value{}, EndPointPath{})
|
||||
|
||||
if Child.IsKnown() {
|
||||
if row == 0 {
|
||||
dt.AddHeader(dt.Reflect)
|
||||
}
|
||||
dt.AddRow(&Child)
|
||||
continue
|
||||
}
|
||||
|
||||
ok, refs := dt.GetTableStruct2(dt.Reflect, &Child)
|
||||
if ok {
|
||||
if row == 0 {
|
||||
dt.AddHeader(refs...)
|
||||
}
|
||||
dt.AddRow(refs...)
|
||||
continue
|
||||
}
|
||||
|
||||
ok, refs = dt.GetTableMap2(dt.Reflect, &Child)
|
||||
if ok {
|
||||
if row == 0 {
|
||||
dt.AddHeader(refs...)
|
||||
}
|
||||
dt.AddRow(refs...)
|
||||
continue
|
||||
}
|
||||
|
||||
ok, refs = dt.GetTableSlice2(dt.Reflect, &Child)
|
||||
if ok {
|
||||
if row == 0 {
|
||||
dt.AddHeader(refs...)
|
||||
}
|
||||
dt.AddRow(refs...)
|
||||
continue
|
||||
}
|
||||
}
|
||||
break
|
||||
}
|
||||
|
||||
if dt.Reflect.Kind == reflect.Slice {
|
||||
// Handle slices here.
|
||||
for row := 0; row < dt.Reflect.Length; row++ {
|
||||
var Child Reflect
|
||||
Child.SetByIndex(*dt.Reflect, *dt.Reflect, row, reflect.Value{}, EndPointPath{})
|
||||
|
||||
if Child.IsKnown() {
|
||||
if row == 0 {
|
||||
dt.AddHeader(dt.Reflect)
|
||||
}
|
||||
dt.AddRow(&Child)
|
||||
continue
|
||||
}
|
||||
|
||||
ok, refs := dt.GetTableStruct2(dt.Reflect, &Child)
|
||||
if ok {
|
||||
if row == 0 {
|
||||
dt.AddHeader(refs...)
|
||||
}
|
||||
dt.AddRow(refs...)
|
||||
continue
|
||||
}
|
||||
|
||||
ok, refs = dt.GetTableMap2(dt.Reflect, &Child)
|
||||
if ok {
|
||||
if row == 0 {
|
||||
dt.AddHeader(refs...)
|
||||
}
|
||||
dt.AddRow(refs...)
|
||||
continue
|
||||
}
|
||||
|
||||
ok, refs = dt.GetTableSlice2(dt.Reflect, &Child)
|
||||
if ok {
|
||||
if row == 0 {
|
||||
dt.AddHeader(refs...)
|
||||
}
|
||||
dt.AddRow(refs...)
|
||||
continue
|
||||
}
|
||||
}
|
||||
break
|
||||
}
|
||||
|
||||
if dt.Reflect.Kind == reflect.Map {
|
||||
// Handle maps here.
|
||||
for row, rowMap := range dt.Reflect.FieldVo.MapKeys() {
|
||||
var Child Reflect
|
||||
Child.SetByIndex(*dt.Reflect, *dt.Reflect, row, rowMap, EndPointPath{})
|
||||
|
||||
if Child.IsKnown() {
|
||||
if row == 0 {
|
||||
dt.AddHeader(dt.Reflect)
|
||||
}
|
||||
dt.AddRow(&Child)
|
||||
continue
|
||||
}
|
||||
|
||||
ok, refs := dt.GetTableStruct2(dt.Reflect, &Child)
|
||||
if ok {
|
||||
if row == 0 {
|
||||
dt.AddHeader(refs...)
|
||||
}
|
||||
dt.AddRow(refs...)
|
||||
continue
|
||||
}
|
||||
|
||||
ok, refs = dt.GetTableMap2(dt.Reflect, &Child)
|
||||
if ok {
|
||||
if row == 0 {
|
||||
dt.AddHeader(refs...)
|
||||
}
|
||||
dt.AddRow(refs...)
|
||||
continue
|
||||
}
|
||||
|
||||
ok, refs = dt.GetTableSlice2(dt.Reflect, &Child)
|
||||
if ok {
|
||||
if row == 0 {
|
||||
dt.AddHeader(refs...)
|
||||
}
|
||||
dt.AddRow(refs...)
|
||||
continue
|
||||
}
|
||||
}
|
||||
break
|
||||
}
|
||||
|
||||
_, _ = fmt.Fprintf(os.Stderr,"ERROR: Field '%s' type not supported (%s): Type %s\n",
|
||||
dt.Reflect.FieldName, dt.Reflect.DataStructure.DataTableId, dt.Reflect.Kind.String())
|
||||
}
|
||||
|
||||
return *dt
|
||||
}
|
||||
|
||||
func (dt *DataTable) GetTableMap2(Parent *Reflect, Child *Reflect) (bool, []*Reflect) {
|
||||
var ok bool
|
||||
var refs []*Reflect
|
||||
|
||||
for range Only.Once {
|
||||
if Child.Kind != reflect.Map {
|
||||
break
|
||||
}
|
||||
|
||||
ok = true
|
||||
for col, colMap := range dt.Reflect.FieldVo.MapKeys() {
|
||||
var ChildStruct Reflect
|
||||
ChildStruct.SetByIndex(*dt.Reflect, *Child, col, colMap, EndPointPath{})
|
||||
|
||||
if dt.GoStructOptions(Parent, Child, &ChildStruct) {
|
||||
continue
|
||||
}
|
||||
|
||||
if dt.Reflect.DataStructure.DataTableSortOn != "" {
|
||||
// fmt.Printf("\tChildStruct> %s / %s\n", ChildStruct.FieldName, dt.Reflect.DataStructure.DataTableSortOn)
|
||||
if dt.Reflect.DataStructure.DataTableSortOn == ChildStruct.FieldName {
|
||||
dt.SortOn = ChildStruct.DataStructure.PointName
|
||||
dt.Reflect.DataStructure.DataTableSortOn = ""
|
||||
}
|
||||
}
|
||||
refs = append(refs, &ChildStruct)
|
||||
}
|
||||
}
|
||||
|
||||
return ok, refs
|
||||
}
|
||||
|
||||
func (dt *DataTable) GetTableSlice2(Parent *Reflect, Child *Reflect) (bool, []*Reflect) {
|
||||
var ok bool
|
||||
var refs []*Reflect
|
||||
|
||||
for range Only.Once {
|
||||
if Child.Kind != reflect.Slice {
|
||||
break
|
||||
}
|
||||
|
||||
ok = true
|
||||
for col := 0; col < Child.Length; col++ {
|
||||
var ChildStruct Reflect
|
||||
ChildStruct.SetByIndex(*dt.Reflect, *Child, col, reflect.Value{}, EndPointPath{})
|
||||
|
||||
if dt.GoStructOptions(Parent, Child, &ChildStruct) {
|
||||
continue
|
||||
}
|
||||
|
||||
if dt.Reflect.DataStructure.DataTableSortOn != "" {
|
||||
// fmt.Printf("\tChildStruct> %s / %s\n", ChildStruct.FieldName, dt.Reflect.DataStructure.DataTableSortOn)
|
||||
if dt.Reflect.DataStructure.DataTableSortOn == ChildStruct.FieldName {
|
||||
dt.SortOn = ChildStruct.DataStructure.PointName
|
||||
dt.Reflect.DataStructure.DataTableSortOn = ""
|
||||
}
|
||||
}
|
||||
refs = append(refs, &ChildStruct)
|
||||
}
|
||||
}
|
||||
|
||||
return ok, refs
|
||||
}
|
||||
|
||||
func (dt *DataTable) GetTableStruct2(Parent *Reflect, Child *Reflect) (bool, []*Reflect) {
|
||||
var ok bool
|
||||
var refs []*Reflect
|
||||
|
||||
for range Only.Once {
|
||||
if Child.Kind != reflect.Struct {
|
||||
break
|
||||
}
|
||||
|
||||
ok = true
|
||||
for col := 0; col < Child.Length; col++ {
|
||||
var ChildStruct Reflect
|
||||
ChildStruct.SetByIndex(*dt.Reflect, *Child, col, reflect.Value{}, EndPointPath{})
|
||||
|
||||
if dt.GoStructOptions(Parent, Child, &ChildStruct) {
|
||||
continue
|
||||
}
|
||||
|
||||
if dt.Reflect.DataStructure.DataTableSortOn != "" {
|
||||
// fmt.Printf("\tChildStruct> %s / %s\n", ChildStruct.FieldName, dt.Reflect.DataStructure.DataTableSortOn)
|
||||
if dt.Reflect.DataStructure.DataTableSortOn == ChildStruct.FieldName {
|
||||
dt.SortOn = ChildStruct.DataStructure.PointName
|
||||
dt.Reflect.DataStructure.DataTableSortOn = ""
|
||||
}
|
||||
}
|
||||
refs = append(refs, &ChildStruct)
|
||||
}
|
||||
}
|
||||
|
||||
return ok, refs
|
||||
}
|
||||
|
||||
func (dt *DataTable) GoStructOptions(Parent *Reflect, Current *Reflect, Child *Reflect) bool {
|
||||
var yes bool
|
||||
for range Only.Once {
|
||||
if Parent.Kind == reflect.Slice {
|
||||
// @TODO - Need to check here if the parent is a slice.
|
||||
// If so - then "parent" is actually Parent.
|
||||
// If not - then "parent" is actually Current.
|
||||
}
|
||||
|
||||
if Child.FieldName != NameGoStruct {
|
||||
break
|
||||
}
|
||||
|
||||
yes = true
|
||||
}
|
||||
return yes
|
||||
}
|
||||
|
||||
|
||||
func (dt *DataTable) AddHeader(headers ...*Reflect) {
|
||||
for range Only.Once {
|
||||
for _, header := range headers {
|
||||
name := valueTypes.PointToName(header.DataStructure.PointId)
|
||||
if header.DataStructure.PointUnit != "" {
|
||||
name += " (" + header.DataStructure.PointUnit + ")"
|
||||
}
|
||||
dt.Headers = append(dt.Headers, name)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (dt *DataTable) AddRow(refs ...*Reflect) {
|
||||
for range Only.Once {
|
||||
if dt.Data == nil {
|
||||
dt.Data = make([][]*Reflect, 0)
|
||||
}
|
||||
|
||||
var row []*Reflect
|
||||
row = append(row, refs...)
|
||||
// for _, ref := range refs {
|
||||
// }
|
||||
dt.Data = append(dt.Data, row)
|
||||
}
|
||||
}
|
||||
|
||||
func (dt *DataTable) GetRow(row int) []*Reflect {
|
||||
return dt.Data[row]
|
||||
}
|
||||
|
||||
func (dt *DataTable) Get() [][]*Reflect {
|
||||
return dt.Data
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
// Package apiReflect - Snaffooed from https://github.com/fatih/structs
|
||||
// Package apiReflect contains various utilities functions to work with structs.
|
||||
package apiReflect
|
||||
// Package GoStruct - Snaffooed from https://github.com/fatih/structs
|
||||
// Package GoStruct contains various utilities functions to work with structs.
|
||||
package GoStruct
|
||||
|
||||
import (
|
||||
"fmt"
|
@ -1,5 +1,5 @@
|
||||
// Package apiReflect - Snaffooed from https://github.com/fatih/structs
|
||||
package apiReflect
|
||||
// Package GoStruct - Snaffooed from https://github.com/fatih/structs
|
||||
package GoStruct
|
||||
|
||||
import "strings"
|
||||
|
@ -113,8 +113,14 @@ func UnitValueType(unit string) string {
|
||||
|
||||
case "F":
|
||||
fallthrough
|
||||
case "°F":
|
||||
fallthrough
|
||||
case "℉":
|
||||
fallthrough
|
||||
case "C":
|
||||
fallthrough
|
||||
case "°C":
|
||||
fallthrough
|
||||
case "℃":
|
||||
ret = "Temperature"
|
||||
}
|
3
iSolarCloud/api/debug.go
Normal file
3
iSolarCloud/api/debug.go
Normal file
@ -0,0 +1,3 @@
|
||||
package api
|
||||
// DEBUG - Used for easy debugging of this package.
|
||||
const DEBUG = false
|
@ -2,8 +2,9 @@ package api
|
||||
|
||||
import (
|
||||
"GoSungrow/Only"
|
||||
"GoSungrow/iSolarCloud/api/apiReflect"
|
||||
"GoSungrow/iSolarCloud/api/output"
|
||||
"GoSungrow/iSolarCloud/api/GoStruct"
|
||||
"GoSungrow/iSolarCloud/api/GoStruct/output"
|
||||
"GoSungrow/iSolarCloud/api/GoStruct/reflection"
|
||||
"errors"
|
||||
"fmt"
|
||||
"github.com/MickMake/GoUnify/cmdPath"
|
||||
@ -14,7 +15,7 @@ import (
|
||||
|
||||
|
||||
func (ep *EndPointStruct) ApiSetFilenamePrefix2(ref interface{}, format string, args ...interface{}) string {
|
||||
f := strings.Join(apiReflect.GetStructValuesAsArray(ref), "-")
|
||||
f := strings.Join(GoStruct.GetStructValuesAsArray(ref), "-")
|
||||
fmt.Printf("[%s]\n", f)
|
||||
if format != "" {
|
||||
ep.FileNamePrefix = fmt.Sprintf(format, args...)
|
||||
@ -171,12 +172,12 @@ func (ep *EndPointStruct) ApiRemoveDataFile() error {
|
||||
}
|
||||
|
||||
func (ep *EndPointStruct) ApiCacheFilename(request interface{}) string {
|
||||
postfix := apiReflect.GetFingerprint(request)
|
||||
postfix := reflection.GetFingerprint(request)
|
||||
return fmt.Sprintf("%s_%s-%s.json", ep.Area, ep.Name, postfix)
|
||||
}
|
||||
|
||||
func (ep *EndPointStruct) ApiFingerprint(request interface{}) string {
|
||||
return apiReflect.GetFingerprint(request)
|
||||
return reflection.GetFingerprint(request)
|
||||
}
|
||||
|
||||
// func (ep *EndPointStruct) ApiCacheFilePath(request interface{}) string {
|
||||
|
@ -1,6 +1,6 @@
|
||||
package api
|
||||
|
||||
import "GoSungrow/iSolarCloud/api/output"
|
||||
import "GoSungrow/iSolarCloud/api/GoStruct/output"
|
||||
|
||||
type Area interface {
|
||||
Init(*Web) AreaStruct
|
||||
|
@ -1,7 +1,7 @@
|
||||
package api
|
||||
|
||||
import (
|
||||
"GoSungrow/iSolarCloud/api/output"
|
||||
"GoSungrow/iSolarCloud/api/GoStruct/output"
|
||||
"time"
|
||||
)
|
||||
|
||||
|
@ -274,7 +274,7 @@ package api
|
||||
// func (dm *DataMap) AddUnitValue(endpoint string, parentId string, pid valueTypes.PointId, name string, groupName string, date valueTypes.DateTime, ref valueTypes.UnitValue) {
|
||||
// for range Only.Once {
|
||||
// if endpoint == "" {
|
||||
// endpoint = apiReflect.GetCallerPackage(2)
|
||||
// endpoint = GoStruct.GetCallerPackage(2)
|
||||
// }
|
||||
//
|
||||
// ref = ref.UnitValueFix()
|
||||
|
@ -1,301 +0,0 @@
|
||||
package output
|
||||
|
||||
import (
|
||||
"GoSungrow/Only"
|
||||
"errors"
|
||||
"fmt"
|
||||
"go.pennock.tech/tabular"
|
||||
datatable "go.pennock.tech/tabular/auto"
|
||||
"os"
|
||||
"reflect"
|
||||
)
|
||||
|
||||
|
||||
type Table struct {
|
||||
filePrefix string
|
||||
title string
|
||||
table datatable.RenderTable
|
||||
graph *Chart
|
||||
json []byte
|
||||
raw []byte
|
||||
OutputType OutputType
|
||||
saveAsFile bool
|
||||
graphFilter string
|
||||
Error error
|
||||
}
|
||||
type Tables map[string]Table
|
||||
|
||||
|
||||
func NewTable() Table {
|
||||
return Table {
|
||||
filePrefix: "",
|
||||
title: "",
|
||||
table: datatable.New("utf8-heavy"),
|
||||
// graph: graph.New(""),
|
||||
Error: nil,
|
||||
}
|
||||
}
|
||||
|
||||
func NewTables() Tables {
|
||||
return make(Tables)
|
||||
}
|
||||
|
||||
func (t *Table) String() string {
|
||||
var ret string
|
||||
for range Only.Once {
|
||||
if t == nil {
|
||||
break
|
||||
}
|
||||
|
||||
ret, t.Error = t.table.Render()
|
||||
if t.Error != nil {
|
||||
break
|
||||
}
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
||||
func (t *Table) GetHeaders() []tabular.Cell {
|
||||
return t.table.Headers()
|
||||
}
|
||||
|
||||
func (t *Table) AllRows() []*tabular.Row {
|
||||
return t.table.AllRows()
|
||||
}
|
||||
|
||||
type DataSet []DataRow
|
||||
type DataRow map[string]string
|
||||
|
||||
func (t *Table) SetTitle(title string, args ...interface{}) {
|
||||
t.title = fmt.Sprintf(title, args...)
|
||||
}
|
||||
|
||||
func (t *Table) SetRaw(data []byte) {
|
||||
t.raw = data
|
||||
}
|
||||
|
||||
func (t *Table) AppendRaw(data []byte) {
|
||||
t.raw = append(t.raw, data...)
|
||||
}
|
||||
|
||||
func (t *Table) SetJson(data []byte) {
|
||||
t.json = data
|
||||
}
|
||||
|
||||
func (t *Table) SetSaveFile(ok bool) {
|
||||
t.saveAsFile = ok
|
||||
}
|
||||
|
||||
func (t *Table) SetGraphFilter(filter string) {
|
||||
t.graphFilter = filter
|
||||
}
|
||||
|
||||
func (t *Table) SetFilePrefix(prefix string) {
|
||||
t.filePrefix = prefix
|
||||
}
|
||||
|
||||
func (t *Table) SetOutputType(outputType string) {
|
||||
t.OutputType.Set(outputType)
|
||||
}
|
||||
|
||||
func (t *Table) SetHeader(header...interface{}) error {
|
||||
t.table.AddHeaders(header...)
|
||||
t.Error = t.getErrors()
|
||||
return t.Error
|
||||
}
|
||||
|
||||
func (t *Table) AddRow(row ...interface{}) error {
|
||||
t.table.AddRowItems(row...)
|
||||
t.Error = t.getErrors()
|
||||
return t.Error
|
||||
}
|
||||
|
||||
func (t *Table) getErrors() error {
|
||||
if errs := t.table.Errors(); errs != nil {
|
||||
for _, err := range errs {
|
||||
t.Error = err
|
||||
break
|
||||
}
|
||||
}
|
||||
return t.Error
|
||||
}
|
||||
|
||||
func (t *Table) writeFile(fn string, data string, perm os.FileMode) error {
|
||||
for range Only.Once {
|
||||
fmt.Printf("Writing file '%s'\n", fn)
|
||||
t.Error = os.WriteFile(fn, []byte(data), perm)
|
||||
if t.Error != nil {
|
||||
t.Error = errors.New(fmt.Sprintf("Unable to write to file %s - %v", fn, t.Error))
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
return t.Error
|
||||
}
|
||||
|
||||
|
||||
func (t *Table) Output() error {
|
||||
for range Only.Once {
|
||||
if t == nil {
|
||||
break
|
||||
}
|
||||
|
||||
// switch {
|
||||
// case sg.OutputType.IsNone():
|
||||
// if sg.Error != nil {
|
||||
// fmt.Println(ret.Help())
|
||||
// break
|
||||
// }
|
||||
//
|
||||
// case sg.OutputType.IsRaw():
|
||||
// // if sg.Error != nil {
|
||||
// // fmt.Println(ret.Help())
|
||||
// // break
|
||||
// // }
|
||||
// if sg.SaveAsFile {
|
||||
// sg.Error = ret.WriteDataFile()
|
||||
// break
|
||||
// }
|
||||
// fmt.Println(ret.GetJsonData(true))
|
||||
//
|
||||
// case sg.OutputType.IsJson():
|
||||
// if sg.Error != nil {
|
||||
// fmt.Println(ret.Help())
|
||||
// break
|
||||
// }
|
||||
// if sg.SaveAsFile {
|
||||
// sg.Error = ret.WriteDataFile()
|
||||
// break
|
||||
// }
|
||||
// fmt.Println(ret.GetJsonData(false))
|
||||
//
|
||||
// default:
|
||||
// if sg.Error != nil {
|
||||
// fmt.Println(ret.Help())
|
||||
// break
|
||||
// }
|
||||
// }
|
||||
|
||||
switch {
|
||||
case t.OutputType.IsNone():
|
||||
|
||||
case t.OutputType.IsTable():
|
||||
t.Error = t.WriteTable()
|
||||
|
||||
case t.OutputType.IsList():
|
||||
t.Error = t.WriteList()
|
||||
|
||||
case t.OutputType.IsCsv():
|
||||
t.Error = t.WriteCsv()
|
||||
|
||||
case t.OutputType.IsRaw():
|
||||
t.Error = t.WriteRaw()
|
||||
|
||||
case t.OutputType.IsJson():
|
||||
t.Error = t.WriteJson()
|
||||
|
||||
case t.OutputType.IsGraph():
|
||||
t.Error = t.SetGraphFromJson(Json(t.graphFilter))
|
||||
if t.Error != nil {
|
||||
break
|
||||
}
|
||||
t.Error = t.CreateGraph()
|
||||
if t.Error != nil {
|
||||
break
|
||||
}
|
||||
|
||||
default:
|
||||
}
|
||||
}
|
||||
|
||||
return t.Error
|
||||
}
|
||||
|
||||
|
||||
func (t *Table) GetTable() string {
|
||||
return t.String()
|
||||
}
|
||||
|
||||
func (t *Table) WriteTable() error {
|
||||
if t.saveAsFile {
|
||||
return t.writeFile(t.filePrefix + "-table.txt", t.String(), DefaultFileMode)
|
||||
}
|
||||
fmt.Printf("# %s\n", t.title)
|
||||
fmt.Print(t.String())
|
||||
return nil
|
||||
}
|
||||
|
||||
func (t *Table) WriteList() error {
|
||||
if t.saveAsFile {
|
||||
return t.writeFile(t.filePrefix + ".txt", t.String(), DefaultFileMode)
|
||||
}
|
||||
fmt.Printf("# %s\n", t.title)
|
||||
fmt.Print(t.String())
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
func (t *Table) GetCsv() string {
|
||||
var ret string
|
||||
for range Only.Once {
|
||||
if t == nil {
|
||||
break
|
||||
}
|
||||
|
||||
for _, h := range t.GetHeaders() {
|
||||
ret += fmt.Sprintf("%s,", h)
|
||||
}
|
||||
ret += fmt.Sprintf("\n")
|
||||
|
||||
for _, r := range t.AllRows() {
|
||||
for _, c := range r.Cells() {
|
||||
switch reflect.ValueOf(c.Item()).Type().Name() {
|
||||
case "string":
|
||||
ret += fmt.Sprintf("\"%s\",", c)
|
||||
default:
|
||||
ret += fmt.Sprintf("%s,", c)
|
||||
}
|
||||
}
|
||||
ret += fmt.Sprintf("\n")
|
||||
}
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
||||
func (t *Table) WriteCsv() error {
|
||||
if t.saveAsFile {
|
||||
return t.writeFile(t.filePrefix+".csv", t.GetCsv(), DefaultFileMode)
|
||||
}
|
||||
fmt.Print(t.GetCsv())
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
func (t *Table) GetJson() string {
|
||||
return string(t.raw)
|
||||
}
|
||||
|
||||
func (t *Table) WriteJson() error {
|
||||
if t.saveAsFile {
|
||||
return t.writeFile(t.filePrefix + ".json", string(t.json), DefaultFileMode)
|
||||
}
|
||||
fmt.Printf("%s", t.json)
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
func (t *Table) GetRaw() string {
|
||||
return string(t.json)
|
||||
}
|
||||
|
||||
func (t *Table) GetRawBytes() []byte {
|
||||
return t.json
|
||||
}
|
||||
|
||||
func (t *Table) WriteRaw() error {
|
||||
if t.saveAsFile {
|
||||
return t.writeFile(t.filePrefix+".raw", string(t.raw), DefaultFileMode)
|
||||
}
|
||||
fmt.Printf("%s", t.raw)
|
||||
return nil
|
||||
}
|
@ -2,7 +2,7 @@ package api
|
||||
|
||||
import (
|
||||
"GoSungrow/Only"
|
||||
"GoSungrow/iSolarCloud/api/output"
|
||||
"GoSungrow/iSolarCloud/api/GoStruct/output"
|
||||
"errors"
|
||||
"fmt"
|
||||
"github.com/olekukonko/tablewriter"
|
||||
|
@ -2,14 +2,13 @@ package api
|
||||
|
||||
import (
|
||||
"GoSungrow/Only"
|
||||
"GoSungrow/iSolarCloud/api/apiReflect"
|
||||
"GoSungrow/iSolarCloud/api/output"
|
||||
"GoSungrow/iSolarCloud/api/valueTypes"
|
||||
"GoSungrow/iSolarCloud/api/GoStruct"
|
||||
"GoSungrow/iSolarCloud/api/GoStruct/output"
|
||||
"GoSungrow/iSolarCloud/api/GoStruct/reflection"
|
||||
"GoSungrow/iSolarCloud/api/GoStruct/valueTypes"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
datatable "go.pennock.tech/tabular/auto"
|
||||
"os"
|
||||
"reflect"
|
||||
"sort"
|
||||
"strings"
|
||||
"time"
|
||||
@ -17,7 +16,6 @@ import (
|
||||
|
||||
|
||||
type DataMap struct {
|
||||
// DataStructures apiReflect.DataStructures
|
||||
Map map[string]*DataEntries
|
||||
Table output.Table
|
||||
DataTables output.Tables
|
||||
@ -30,21 +28,23 @@ func NewDataMap() DataMap {
|
||||
}
|
||||
}
|
||||
|
||||
func (dm *DataMap) StructToDataMap(endpoint EndPoint, parentDeviceId string, name apiReflect.EndPointPath) {
|
||||
func (dm *DataMap) StructToDataMap(endpoint EndPoint, parentDeviceId string, name GoStruct.EndPointPath) DataMap {
|
||||
for range Only.Once {
|
||||
epName := apiReflect.NewEndPointPath(apiReflect.GetName("", endpoint))
|
||||
epName := GoStruct.NewEndPointPath(reflection.GetName("", endpoint))
|
||||
name = epName.Append(name...)
|
||||
|
||||
timestamp := valueTypes.SetDateTimeValue(time.Now().Round(5 * time.Minute))
|
||||
|
||||
// Iterate over all available fields and read the tag values
|
||||
var tp apiReflect.DataStructures
|
||||
var Parent GoStruct.Reflect
|
||||
Parent.SetByFieldName(endpoint.ResponseRef(), endpoint.ResponseRef(), name[0])
|
||||
Current := GoStruct.FindStart("ResultData", Parent, Parent, name)
|
||||
name = Current.DataStructure.Endpoint.Copy()
|
||||
|
||||
var tp GoStruct.DataStructures
|
||||
tp.Debug = false
|
||||
tp.ShowEmpty = true
|
||||
var Ref apiReflect.Reflect
|
||||
Ref.SetByFieldName(endpoint.ResponseRef(), endpoint.ResponseRef(), "")
|
||||
Ref = FindResultData(Ref, Ref)
|
||||
tp.GetPointTags(Ref, Ref, name)
|
||||
tp.GetPointTags(&Parent, Current, name)
|
||||
|
||||
// Convert to DataMap
|
||||
for _, f := range tp.DataMap {
|
||||
@ -65,7 +65,10 @@ func (dm *DataMap) StructToDataMap(endpoint EndPoint, parentDeviceId string, nam
|
||||
}
|
||||
|
||||
// fmt.Printf("DEBUG: StructToPoints(): %s / %s\n", f.Endpoint, f.PointId)
|
||||
uvs, _, ok := valueTypes.AnyToUnitValue(f.Value, f.PointUnit, f.PointValueType, valueTypes.DateTimeLayout)
|
||||
if f.PointNameDateFormat == "" {
|
||||
f.PointNameDateFormat = valueTypes.DateTimeLayout
|
||||
}
|
||||
uvs, _, ok := valueTypes.AnyToUnitValue(f.Value, f.PointUnit, f.PointValueType, f.PointNameDateFormat)
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
@ -110,160 +113,20 @@ func (dm *DataMap) StructToDataMap(endpoint EndPoint, parentDeviceId string, nam
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Create data tables.
|
||||
dm.Table = dm.CreateEndPointResultTable()
|
||||
dm.Table.SetTitle(fmt.Sprintf("EndPoint Data: %s", name))
|
||||
dm.Table.SetFilePrefix(fmt.Sprintf("%s_%s", endpoint.GetArea(), endpoint.GetName()))
|
||||
dm.Table.SetTitle("EndPoint Data: %s", name)
|
||||
dm.Table.SetFilePrefix("%s_%s", endpoint.GetArea(), endpoint.GetName())
|
||||
dm.Table.SetJson([]byte(endpoint.GetJsonData(false)))
|
||||
dm.Table.SetRaw([]byte(endpoint.GetJsonData(true)))
|
||||
|
||||
dm.DataTables = output.NewTables()
|
||||
if tp.DataTables.Merge {
|
||||
var data [][]interface{}
|
||||
var headers []interface{}
|
||||
|
||||
if tp.DataTables.Index {
|
||||
headers = append(headers, "Date/Time", "Index")
|
||||
}
|
||||
|
||||
for _, f := range tp.DataTables.Get() {
|
||||
if f == nil {
|
||||
continue
|
||||
}
|
||||
if !f.Reflect.DataStructure.DataTable {
|
||||
continue
|
||||
}
|
||||
|
||||
dt := f.GetTable()
|
||||
for index := range dt.Headers {
|
||||
headers = append(headers, dt.Headers[index])
|
||||
}
|
||||
|
||||
for rowIndex, _ := range dt.Data {
|
||||
if data == nil {
|
||||
data = make([][]interface{}, 0)
|
||||
}
|
||||
for _, col := range dt.Data[rowIndex] {
|
||||
// uvs, _, ok := valueTypes.AnyToUnitValue(col.DataStructure.Value, col.DataStructure.PointUnit, col.DataStructure.PointValueType, valueTypes.DateTimeLayout)
|
||||
// if !ok {
|
||||
// continue
|
||||
// }
|
||||
|
||||
if (len(data) - 1) < rowIndex {
|
||||
var d []interface{}
|
||||
d = append(d, col.DataStructure.Value)
|
||||
data = append(data, d)
|
||||
continue
|
||||
}
|
||||
// data[rowIndex] = append(data[rowIndex], uvs[0].String())
|
||||
data[rowIndex] = append(data[rowIndex], col.DataStructure.Value)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if tp.DataTables.Index {
|
||||
for i := range data {
|
||||
var t []interface{}
|
||||
t = append(t, timestamp.String(), i)
|
||||
data[i] = append(t, data[i]...)
|
||||
}
|
||||
}
|
||||
|
||||
table := output.NewTable()
|
||||
for i := range data {
|
||||
// fmt.Printf("DEBUG: StructToPoints(): %s / %s\n", f.Endpoint, f.PointId)
|
||||
|
||||
_ = table.AddRow(data[i]...)
|
||||
}
|
||||
_ = table.SetHeader(headers...)
|
||||
table.SetTitle(fmt.Sprintf("Table %s-%s - (%s)", endpoint.GetArea(), endpoint.GetName(), parentDeviceId))
|
||||
table.SetFilePrefix(fmt.Sprintf("%s-%s-%s", endpoint.GetArea(), endpoint.GetName(), parentDeviceId))
|
||||
table.SetGraphFilter("")
|
||||
dm.DataTables[fmt.Sprintf("%s.%s", endpoint.GetArea(), endpoint.GetName())] = table
|
||||
break
|
||||
}
|
||||
|
||||
// for _, f := range tp.DataTables.Get() {
|
||||
// if f == nil {
|
||||
// continue
|
||||
// }
|
||||
// if !f.Reflect.DataStructure.DataTable {
|
||||
// continue
|
||||
// }
|
||||
//
|
||||
// dt := f.GetTable()
|
||||
// for index := range dt.Headers {
|
||||
// headers = append(headers, dt.Headers[index])
|
||||
// }
|
||||
//
|
||||
// for rowIndex, _ := range dt.Data {
|
||||
// if data == nil {
|
||||
// data = make([][]interface{}, 0)
|
||||
// }
|
||||
// for _, col := range dt.Data[rowIndex] {
|
||||
// uvs, _, ok := valueTypes.AnyToUnitValue(col.DataStructure.Value, col.DataStructure.PointUnit, col.DataStructure.PointValueType, valueTypes.DateTimeLayout)
|
||||
// if !ok {
|
||||
// continue
|
||||
// }
|
||||
//
|
||||
// // var point Point
|
||||
// // p := GetPoint(strings.Join(col.DataStructure.Endpoint, ".") + "." + col.DataStructure.PointId)
|
||||
// // if p == nil {
|
||||
// // // No point found. Create one.
|
||||
// // point = CreatePoint(parentDeviceId, valueTypes.SetPointIdString(col.DataStructure.PointId), col.DataStructure.PointName, col.DataStructure.PointGroupName, uvs.Unit(), uvs.Type(), col.DataStructure.PointUpdateFreq)
|
||||
// // } else {
|
||||
// // point = *p
|
||||
// // }
|
||||
// // point.UpdateFreq = col.DataStructure.PointUpdateFreq
|
||||
// // point.SetName(col.DataStructure.PointName)
|
||||
//
|
||||
// if (len(data) - 1) < rowIndex {
|
||||
// var d []interface{}
|
||||
// d = append(d, uvs[0].String())
|
||||
// data = append(data, d)
|
||||
// continue
|
||||
// }
|
||||
// data[rowIndex] = append(data[rowIndex], uvs[0].String())
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
for _, f := range tp.DataTables.Get() {
|
||||
if !f.Reflect.DataStructure.DataTable {
|
||||
continue
|
||||
}
|
||||
|
||||
table := output.NewTable()
|
||||
dt := f.GetTable()
|
||||
|
||||
var headers []interface{}
|
||||
for _, h := range dt.Headers {
|
||||
headers = append(headers, h)
|
||||
}
|
||||
_ = table.SetHeader(headers...)
|
||||
|
||||
for row := range dt.Data {
|
||||
var data []interface{}
|
||||
for _, col := range dt.Data[row] {
|
||||
data = append(data, col.DataStructure.Value)
|
||||
}
|
||||
_ = table.AddRow(data...)
|
||||
}
|
||||
title := dt.Reflect.DataStructure.DataTableTitle
|
||||
if title == "" {
|
||||
title = dt.Reflect.DataStructure.DataTableName
|
||||
}
|
||||
if title == "" {
|
||||
title = dt.Reflect.DataStructure.DataTableId
|
||||
}
|
||||
|
||||
table.SetTitle(fmt.Sprintf("List %s-%s - %s", endpoint.GetArea(), endpoint.GetName(), title))
|
||||
table.SetFilePrefix(fmt.Sprintf("%s-%s-%s", endpoint.GetArea(), endpoint.GetName(), dt.Reflect.DataStructure.DataTableId))
|
||||
table.SetGraphFilter("")
|
||||
dm.DataTables[dt.Reflect.DataStructure.DataTableId] = table
|
||||
}
|
||||
dm.DataTables = tp.DataTables.GetDataMergedTables(timestamp, parentDeviceId)
|
||||
dm.DataTables = tp.DataTables.GetDataTables()
|
||||
// dm.GetDataMergedTables(endpoint, tp.DataTables, timestamp, parentDeviceId)
|
||||
// dm.GetDataTables(endpoint, tp.DataTables)
|
||||
}
|
||||
return *dm
|
||||
}
|
||||
|
||||
func (dm *DataMap) AddPointUnitValue(endpoint string, parentDeviceId string, point Point, date valueTypes.DateTime, uv valueTypes.UnitValue) {
|
||||
@ -451,20 +314,29 @@ func (dm *DataMap) TableSort() []string {
|
||||
}
|
||||
|
||||
func (dm *DataMap) CreateEndPointResultTable() output.Table {
|
||||
table := output.NewTable()
|
||||
table := output.NewTable(
|
||||
"Date",
|
||||
"Point Id",
|
||||
"Value",
|
||||
"Unit",
|
||||
"Unit Type",
|
||||
"Group Name",
|
||||
"Description",
|
||||
"Update Freq",
|
||||
)
|
||||
|
||||
for range Only.Once {
|
||||
for _, p := range dm.Sort() {
|
||||
_ = table.SetHeader(
|
||||
"Date",
|
||||
"Point Id",
|
||||
"Value",
|
||||
"Unit",
|
||||
"Unit Type",
|
||||
"Group Name",
|
||||
"Description",
|
||||
"Update Freq",
|
||||
)
|
||||
// _ = table.SetHeader(
|
||||
// "Date",
|
||||
// "Point Id",
|
||||
// "Value",
|
||||
// "Unit",
|
||||
// "Unit Type",
|
||||
// "Group Name",
|
||||
// "Description",
|
||||
// "Update Freq",
|
||||
// )
|
||||
|
||||
entries := dm.Map[p].Entries
|
||||
for _, de := range entries {
|
||||
@ -472,10 +344,9 @@ func (dm *DataMap) CreateEndPointResultTable() output.Table {
|
||||
continue
|
||||
}
|
||||
|
||||
_ = table.AddRow(
|
||||
de.Date.Format(valueTypes.DateTimeLayout),
|
||||
_ = table.AddRow(de.Date.Format(valueTypes.DateTimeLayout),
|
||||
p,
|
||||
de.Value,
|
||||
de.Value.String(),
|
||||
de.Point.Unit,
|
||||
de.Point.ValueType,
|
||||
de.Point.GroupName,
|
||||
@ -626,58 +497,3 @@ func JoinWithDots(intSize int, dateFormat string, args ...interface{}) string {
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
||||
func FindResultData(Parent apiReflect.Reflect, Current apiReflect.Reflect) apiReflect.Reflect {
|
||||
var ret apiReflect.Reflect
|
||||
|
||||
for range Only.Once {
|
||||
if Current.Kind == reflect.Pointer {
|
||||
// Special case:
|
||||
// We're going to change the pointer to a proper object reference.
|
||||
if Current.IsNil {
|
||||
break
|
||||
}
|
||||
ref2 := Current.ValueOf.Elem().Interface()
|
||||
if valueTypes.IsNil(ref2) {
|
||||
break
|
||||
}
|
||||
Current.SetByFieldName(Current.Interface, ref2, "")
|
||||
if Current.IsNil {
|
||||
break
|
||||
}
|
||||
// DO NOT BREAK!
|
||||
// KEEP FIRST!
|
||||
}
|
||||
|
||||
if Current.Kind == reflect.Struct {
|
||||
// Iterate over all available fields and read the tag value
|
||||
for si := 0; si < Current.Length; si++ {
|
||||
var Child apiReflect.Reflect
|
||||
Child.SetByIndex(Parent, Current, si, apiReflect.EndPointPath{})
|
||||
if Child.DataStructure.PointId == "result_data" {
|
||||
ret = Child
|
||||
break
|
||||
}
|
||||
|
||||
if Child.Kind != reflect.Struct {
|
||||
continue
|
||||
}
|
||||
|
||||
if Child.IsKnown() {
|
||||
continue
|
||||
}
|
||||
|
||||
Child = FindResultData(Current, Child)
|
||||
if Child.DataStructure.PointId == "ResultData" {
|
||||
ret = Child
|
||||
break
|
||||
}
|
||||
}
|
||||
break
|
||||
}
|
||||
|
||||
_, _ = fmt.Fprintf(os.Stderr,"ERROR: Field '%s' type not supported: Type %s\n", Current.FieldName, Current.Kind.String())
|
||||
}
|
||||
|
||||
return ret
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
package api
|
||||
|
||||
import (
|
||||
"GoSungrow/iSolarCloud/api/valueTypes"
|
||||
"GoSungrow/iSolarCloud/api/GoStruct/valueTypes"
|
||||
"github.com/MickMake/GoUnify/Only"
|
||||
)
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
package api
|
||||
|
||||
import (
|
||||
"GoSungrow/iSolarCloud/api/valueTypes"
|
||||
"GoSungrow/iSolarCloud/api/GoStruct/valueTypes"
|
||||
"github.com/MickMake/GoUnify/Only"
|
||||
)
|
||||
|
||||
|
@ -2,8 +2,8 @@ package api
|
||||
|
||||
import (
|
||||
"GoSungrow/Only"
|
||||
"GoSungrow/iSolarCloud/api/apiReflect"
|
||||
"GoSungrow/iSolarCloud/api/output"
|
||||
"GoSungrow/iSolarCloud/api/GoStruct"
|
||||
"GoSungrow/iSolarCloud/api/GoStruct/output"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
@ -12,6 +12,10 @@ import (
|
||||
|
||||
type EndPointName string
|
||||
|
||||
func (n EndPointName) String() string {
|
||||
return string(n)
|
||||
}
|
||||
|
||||
type EndPointStruct struct {
|
||||
ApiRoot Web `json:"-"`
|
||||
RawResponse []byte
|
||||
@ -118,9 +122,10 @@ func (ep EndPointStruct) ResponseAsJson(raw bool, r interface{}) output.Json {
|
||||
}
|
||||
|
||||
func (ep EndPointStruct) ApiGetRequestArgNames(req interface{}) map[string]string {
|
||||
return apiReflect.GetStructFields(req)
|
||||
return GoStruct.GetStructFields(req)
|
||||
}
|
||||
|
||||
|
||||
func MarshalJSON(endpoint EndPoint) ([]byte, error) {
|
||||
e := endpoint.SetError("")
|
||||
j, err := json.Marshal(&struct {
|
||||
|
@ -2,8 +2,8 @@ package api
|
||||
|
||||
import (
|
||||
"GoSungrow/Only"
|
||||
"GoSungrow/iSolarCloud/api/apiReflect"
|
||||
"GoSungrow/iSolarCloud/api/valueTypes"
|
||||
"GoSungrow/iSolarCloud/api/GoStruct"
|
||||
"GoSungrow/iSolarCloud/api/GoStruct/valueTypes"
|
||||
"fmt"
|
||||
"strings"
|
||||
"time"
|
||||
@ -76,35 +76,35 @@ func (p Point) String() string {
|
||||
}
|
||||
|
||||
func (p Point) IsInstant() bool {
|
||||
if p.UpdateFreq == apiReflect.UpdateFreqInstant {
|
||||
if p.UpdateFreq == GoStruct.UpdateFreqInstant {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (p Point) IsDaily() bool {
|
||||
if p.UpdateFreq == apiReflect.UpdateFreqDay {
|
||||
if p.UpdateFreq == GoStruct.UpdateFreqDay {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (p Point) IsMonthly() bool {
|
||||
if p.UpdateFreq == apiReflect.UpdateFreqMonth {
|
||||
if p.UpdateFreq == GoStruct.UpdateFreqMonth {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (p Point) IsYearly() bool {
|
||||
if p.UpdateFreq == apiReflect.UpdateFreqYear {
|
||||
if p.UpdateFreq == GoStruct.UpdateFreqYear {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (p Point) IsTotal() bool {
|
||||
if p.UpdateFreq == apiReflect.UpdateFreqTotal {
|
||||
if p.UpdateFreq == GoStruct.UpdateFreqTotal {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
|
@ -15,7 +15,6 @@ type Response struct {
|
||||
type ResponseCommon struct {
|
||||
ReqSerialNum string `json:"req_serial_num"`
|
||||
ResultCode string `json:"result_code"`
|
||||
ResultData []interface{} `json:"result_data"`
|
||||
ResultMsg string `json:"result_msg"`
|
||||
}
|
||||
|
||||
|
@ -2,7 +2,7 @@ package api
|
||||
|
||||
import (
|
||||
"GoSungrow/Only"
|
||||
"GoSungrow/iSolarCloud/api/valueTypes"
|
||||
"GoSungrow/iSolarCloud/api/GoStruct/valueTypes"
|
||||
"fmt"
|
||||
"strings"
|
||||
)
|
||||
|
@ -1,7 +1,7 @@
|
||||
package api
|
||||
|
||||
import (
|
||||
"GoSungrow/iSolarCloud/api/output"
|
||||
"GoSungrow/iSolarCloud/api/GoStruct/output"
|
||||
)
|
||||
|
||||
|
||||
@ -35,12 +35,12 @@ func (e *Web) ApiGetEndPointDataTables(endpoint EndPoint) output.Tables {
|
||||
table := output.NewTables()
|
||||
// for range Only.Once {
|
||||
//
|
||||
// var tp apiReflect.DataStructures
|
||||
// var tp GoStruct.DataStructures
|
||||
// tp.Debug = true
|
||||
// tp.ShowEmpty = true
|
||||
// var Ref apiReflect.Reflect
|
||||
// var Ref GoStruct.Reflect
|
||||
// Ref.SetByFieldName(endpoint.ResponseRef(), endpoint.ResponseRef(), "")
|
||||
// // tp.FindDataTables(Ref, Ref, apiReflect.EndPointPath{}, false)
|
||||
// // tp.FindDataTables(Ref, Ref, GoStruct.EndPointPath{}, false)
|
||||
//
|
||||
// // data := endpoint.GetEndPointData()
|
||||
// //
|
||||
|
@ -2,7 +2,7 @@ package api
|
||||
|
||||
import (
|
||||
"GoSungrow/Only"
|
||||
"GoSungrow/iSolarCloud/api/apiReflect"
|
||||
"GoSungrow/iSolarCloud/api/GoStruct/reflection"
|
||||
"fmt"
|
||||
"net/url"
|
||||
"reflect"
|
||||
@ -37,11 +37,11 @@ func AppendUrl(host string, endpoint string) *url.URL {
|
||||
}
|
||||
|
||||
func GetArea(v interface{}) AreaName {
|
||||
return AreaName(apiReflect.GetArea(thisPackagePath, v))
|
||||
return AreaName(reflection.GetArea(thisPackagePath, v))
|
||||
}
|
||||
|
||||
func GetName(v interface{}) EndPointName {
|
||||
return EndPointName(apiReflect.GetName(thisPackagePath, v))
|
||||
return EndPointName(reflection.GetName(thisPackagePath, v))
|
||||
}
|
||||
|
||||
func GetUrl(u string) *url.URL {
|
||||
@ -59,7 +59,7 @@ func GetUrl(u string) *url.URL {
|
||||
// func GetStructKeys(ref interface{}, keys ...string) valueTypes.UnitValueMap {
|
||||
// ret := make(valueTypes.UnitValueMap)
|
||||
//
|
||||
// for _, k := range apiReflect.GetStructKeys(ref, keys...) {
|
||||
// for _, k := range GoStruct.GetStructKeys(ref, keys...) {
|
||||
// // p := UnitValue { Value: k.Value, Unit: "" }
|
||||
// p := valueTypes.SetUnitValueString(k.Value, "", "")
|
||||
// if k.Type.Name() == "UnitValue" {
|
||||
|
@ -2,8 +2,8 @@ package api
|
||||
|
||||
import (
|
||||
"GoSungrow/Only"
|
||||
"GoSungrow/iSolarCloud/api/apiReflect"
|
||||
"GoSungrow/iSolarCloud/api/output"
|
||||
"GoSungrow/iSolarCloud/api/GoStruct"
|
||||
"GoSungrow/iSolarCloud/api/GoStruct/output"
|
||||
"github.com/MickMake/GoUnify/cmdPath"
|
||||
"path/filepath"
|
||||
"time"
|
||||
@ -107,7 +107,7 @@ func (w *Web) Get(endpoint EndPoint) EndPoint {
|
||||
func (w *Web) getApi(endpoint EndPoint) ([]byte, error) {
|
||||
for range Only.Once {
|
||||
request := endpoint.RequestRef()
|
||||
w.Error = apiReflect.VerifyOptionsRequired(request)
|
||||
w.Error = GoStruct.VerifyOptionsRequired(request)
|
||||
if w.Error != nil {
|
||||
break
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user