iobroker.sbfspot 4.4.2 → 5.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -32,11 +32,13 @@ This adapter reads data from SMA power inverters using sbfspot.
32
32
  Now both database types (mySQL and sqlite) are supported.
33
33
  Since version 0.2.3 there is a own vis widget based on flot available to show historical data.
34
34
 
35
- ## Installation
35
+ ## Installation / Update
36
36
 
37
37
  please follow installation instructions for sbfspot under https://github.com/SBFspot/SBFspot/wiki
38
38
 
39
- [detailed installation on arm based systems ](docs/en/install_arm.md)
39
+
40
+ in /opt/iobroker/node_modules/iobroker.sbfspot/lib/scripts you can find a scripts to install and update SBFspot on debian based systems.
41
+
40
42
 
41
43
  ## Hints
42
44
  * use latest version from sbfspot from https://github.com/SBFspot/SBFspot
@@ -63,6 +65,14 @@ sometimes npm intall must be called more then one time to successfully install a
63
65
  Placeholder for the next version (at the beginning of the line):
64
66
  ### **WORK IN PROGRESS**
65
67
  -->
68
+ ### 5.0.1 (2025-06-29)
69
+ * (René) new testing
70
+
71
+ ### 5.0.0 (2025-06-07)
72
+ * (René) ATTENTION breaking change: adapter type changed from scheduled to daemon
73
+ * (René) update hints added to admin
74
+ * (René) suggestions from adapter checker
75
+
66
76
  ### 4.4.2 (2025-02-27)
67
77
  * (René) changes requested by adapter checker
68
78
  * (René) dependencies updated
@@ -1,24 +1,32 @@
1
1
  {
2
- "Attention": "adapter, sbfspot und Datenbank sollten auf demselben System laufen",
3
- "GetDataOnlyWhenDaylight": "Daten nur bei Tageslicht abrufen",
4
- "History4Vis2": "History für VIS-2-Widgets erstellen",
5
- "configuration": "Konfiguration",
6
- "install_date": "Installationsdatum der PV-Anlage",
7
- "install_date_desc": "verwendet für die Berechnung der History in vis Widget",
8
- "mySQL, MariaDB configuration": "mySQL, MariaDB-Konfiguration",
9
- "page-mysql": "mySQL / MariaDB",
10
- "page-sqlite": "SQLite",
11
- "path_to_DB_file": "Pfad zur SQLite-Datenbankdatei",
12
- "path_to_DB_file_descr": "geben Sie den kompletten Pfad inkl. Datenbankdateiname an, z.B. /home/pi/sbfspot/smadata/SBFspot.db",
13
- "sbfspot_DB_IP": "Datenbank-IP",
14
- "sbfspot_DB_IP_descr": "Sie können \"localhost\" als IP verwenden",
15
- "sbfspot_DB_databasename": "Datenbank-Name",
16
- "sbfspot_DB_password": "Kennwort des Datenbank-Benutzers",
17
- "sbfspot_DB_port": "Datenbankport",
18
- "sbfspot_DB_port_descr": "Standard 3306",
19
- "sbfspot_DB_user": "Benutzer der Datenbank",
20
- "sbfspot_adapter_settings": "sbfspot Adapter Einstellungen",
21
- "sqlite configuration": "SQLite-Konfiguration",
22
- "type_of_DB": "Type der Datenbank",
23
- "used to calculate statistics": "Wird zur Berechnung statistischer Daten verwendet"
2
+ "Attention": "adapter, sbfspot und Datenbank sollten auf demselben System laufen",
3
+ "GetDataOnlyWhenDaylight": "Daten nur bei Tageslicht abrufen",
4
+ "History4Vis2": "History für VIS-2-Widgets erstellen",
5
+ "configuration": "Konfiguration",
6
+ "install_date": "Installationsdatum der PV-Anlage",
7
+ "install_date_desc": "verwendet für die Berechnung der History in vis Widget",
8
+ "mySQL, MariaDB configuration": "mySQL, MariaDB-Konfiguration",
9
+ "page-mysql": "mySQL / MariaDB",
10
+ "page-sqlite": "SQLite",
11
+ "path_to_DB_file": "Pfad zur SQLite-Datenbankdatei",
12
+ "path_to_DB_file_descr": "geben Sie den kompletten Pfad inkl. Datenbankdateiname an, z.B. /home/pi/sbfspot/smadata/SBFspot.db",
13
+ "sbfspot_DB_IP": "Datenbank-IP",
14
+ "sbfspot_DB_IP_descr": "Sie können \"localhost\" als IP verwenden",
15
+ "sbfspot_DB_databasename": "Datenbank-Name",
16
+ "sbfspot_DB_password": "Kennwort des Datenbank-Benutzers",
17
+ "sbfspot_DB_port": "Datenbankport",
18
+ "sbfspot_DB_port_descr": "Standard 3306",
19
+ "sbfspot_DB_user": "Benutzer der Datenbank",
20
+ "sbfspot_adapter_settings": "sbfspot Adapter Einstellungen",
21
+ "sqlite configuration": "SQLite-Konfiguration",
22
+ "type_of_DB": "Type der Datenbank",
23
+ "used to calculate statistics": "Wird zur Berechnung statistischer Daten verwendet",
24
+
25
+
26
+ "current installed version": "aktuell installierte Version",
27
+ "available version": "verfügbare Version",
28
+ "supported version": "derzeit vom Adapter unterstützte Version",
29
+ "Update hint": "Updatehinweis für SBFspot",
30
+ "link to sbfspot wiki with installation instruction": "Link zum SBFspot-Wiki mit Installationsanweisungen",
31
+ "readIntervalsbfspot": "Intervall zum Lesen von Daten aus der SBFspot-Datenbank [min]"
24
32
  }
@@ -1,24 +1,32 @@
1
1
  {
2
- "Attention": "adapter, sbfspot and database should run on the same system",
3
- "GetDataOnlyWhenDaylight": "get data only when daylight",
4
- "History4Vis2": "Create history value for VIS-2 widget",
5
- "configuration": "configuration",
6
- "install_date": "install date PV-System",
7
- "install_date_desc": "used for calculation of history in vis widget",
8
- "mySQL, MariaDB configuration": "mySQL, MariaDB configuration",
9
- "page-mysql": "mySQL / MariaDB",
10
- "page-sqlite": "SQLite",
11
- "path_to_DB_file": "path to SQLite database file",
12
- "path_to_DB_file_descr": "enter the complete path incl. database file name e.g. /home/pi/sbfspot/smadata/SBFspot.db",
13
- "sbfspot_DB_IP": "database IP",
14
- "sbfspot_DB_IP_descr": "you can use 'localhost' as IP",
15
- "sbfspot_DB_databasename": "database name",
16
- "sbfspot_DB_password": "database password",
17
- "sbfspot_DB_port": "database port",
18
- "sbfspot_DB_port_descr": "default 3306",
19
- "sbfspot_DB_user": "database user",
20
- "sbfspot_adapter_settings": "sbfspot adapter settings",
21
- "sqlite configuration": "SQLite configuration",
22
- "type_of_DB": "type of database",
23
- "used to calculate statistics": "used to calculate statistic data"
2
+ "Attention": "adapter, sbfspot and database should run on the same system",
3
+ "GetDataOnlyWhenDaylight": "get data only when daylight",
4
+ "History4Vis2": "Create history value for VIS-2 widget",
5
+ "configuration": "configuration",
6
+ "install_date": "install date PV-System",
7
+ "install_date_desc": "used for calculation of history in vis widget",
8
+ "mySQL, MariaDB configuration": "mySQL, MariaDB configuration",
9
+ "page-mysql": "mySQL / MariaDB",
10
+ "page-sqlite": "SQLite",
11
+ "path_to_DB_file": "path to SQLite database file",
12
+ "path_to_DB_file_descr": "enter the complete path incl. database file name e.g. /home/pi/sbfspot/smadata/SBFspot.db",
13
+ "sbfspot_DB_IP": "database IP",
14
+ "sbfspot_DB_IP_descr": "you can use 'localhost' as IP",
15
+ "sbfspot_DB_databasename": "database name",
16
+ "sbfspot_DB_password": "database password",
17
+ "sbfspot_DB_port": "database port",
18
+ "sbfspot_DB_port_descr": "default 3306",
19
+ "sbfspot_DB_user": "database user",
20
+ "sbfspot_adapter_settings": "sbfspot adapter settings",
21
+ "sqlite configuration": "SQLite configuration",
22
+ "type_of_DB": "type of database",
23
+ "used to calculate statistics": "used to calculate statistic data",
24
+
25
+
26
+ "current installed version": "current installed version",
27
+ "available version": "available version",
28
+ "supported version": "supported version",
29
+ "Update hint": "update hint",
30
+ "link to sbfspot wiki with installation instruction": "link to SBFspot wiki with installation instruction",
31
+ "readIntervalsbfspot": "interval to read data from SBFspot database [min]"
24
32
  }
@@ -18,6 +18,141 @@
18
18
  "xl": 1.2
19
19
  },
20
20
 
21
+ "InstallUpdatehdr": {
22
+ "type": "header",
23
+ "text": "Update hint",
24
+ "size": 2
25
+ },
26
+
27
+ "currentversiontxt": {
28
+ "type": "staticText",
29
+ "newLine": true,
30
+ "text": "current installed version",
31
+ "xs": 12,
32
+ "sm": 2,
33
+ "md": 2,
34
+ "lg": 2,
35
+ "xl": 2
36
+ },
37
+
38
+ "currentversion": {
39
+ "type": "textSendTo",
40
+ "label": "current istalled sbfspot version",
41
+ "command": "checkCurrentVersion",
42
+ "jsonData": "{\"test\": \"aaa\", \"test2\": \"bbb\" }",
43
+ "alsoDependsOn": [ "checkCurrentVersion" ],
44
+ "xs": 12,
45
+ "sm": 12,
46
+ "md": 6,
47
+ "lg": 4,
48
+ "xl": 4
49
+
50
+ },
51
+
52
+ "installableversiontxt": {
53
+ "type": "staticText",
54
+ "newLine": true,
55
+ "text": "available version",
56
+ "xs": 12,
57
+ "sm": 2,
58
+ "md": 2,
59
+ "lg": 2,
60
+ "xl": 2
61
+ },
62
+ "installableversion": {
63
+ "type": "textSendTo",
64
+ "label": "available version",
65
+ "command": "checkInstallableversion",
66
+ "jsonData": "{\"test\": \"aaa\", \"test2\": \"bbb\" }",
67
+ "alsoDependsOn": [ "checkInstallableversion" ],
68
+ "xs": 12,
69
+ "sm": 12,
70
+ "md": 6,
71
+ "lg": 4,
72
+ "xl": 4
73
+ },
74
+
75
+ "supportedversiontxt": {
76
+ "type": "staticText",
77
+ "newLine": true,
78
+ "text": "supported version",
79
+ "xs": 12,
80
+ "sm": 2,
81
+ "md": 2,
82
+ "lg": 2,
83
+ "xl": 2
84
+ },
85
+ "supportedversion": {
86
+ "type": "textSendTo",
87
+ "label": "supported version",
88
+ "command": "checkSupportedVersion",
89
+ "jsonData": "{\"test\": \"aaa\", \"test2\": \"bbb\" }",
90
+ "alsoDependsOn": [ "checkSupportedversion" ],
91
+ "xs": 12,
92
+ "sm": 12,
93
+ "md": 6,
94
+ "lg": 4,
95
+ "xl": 4
96
+
97
+ },
98
+
99
+
100
+
101
+ //just a link
102
+ "EbusReadme": {
103
+ "type": "staticLink",
104
+ "text": "link to sbfspot wiki with installation instruction",
105
+ "href": "https://github.com/SBFspot/SBFspot/wiki",
106
+ "button": true,
107
+ "icon": "info",
108
+ "newLine": true,
109
+ "xs": 12,
110
+ "sm": 12,
111
+ "md": 6,
112
+ "lg": 4,
113
+ "xl": 4
114
+ },
115
+ //für debian based systeme
116
+ /*
117
+ "sbfspothintinstallUpdate": {
118
+ "type": "staticText",
119
+ "text": "hint_sbfspot_installupdate",
120
+ "newLine": true,
121
+ "xs": 12,
122
+ "sm": 12,
123
+ "md": 12,
124
+ "lg": 12,
125
+ "xl": 12
126
+ } ,
127
+ */
128
+ /* "Install": {
129
+ "type": "sendTo",
130
+ "command": "Install",
131
+ "label": "InstallBtn",
132
+ "tooltip": "InstallBtnHint",
133
+ "newLine": true,
134
+ "xs": 12,
135
+ "sm": 12,
136
+ "md": 12,
137
+ "lg": 12,
138
+ "xl": 12
139
+ },
140
+ "Update": {
141
+ "type": "sendTo",
142
+ "command": "Update",
143
+ "label": "UpdateBtn",
144
+ "tooltip": "UpdateBtnHint",
145
+ "newLine": true,
146
+ "xs": 12,
147
+ "sm": 12,
148
+ "md": 12,
149
+ "lg": 12,
150
+ "xl": 12
151
+ }
152
+ */
153
+
154
+
155
+
21
156
  "dividerHdr1": {
22
157
  "newLine": true,
23
158
  "type": "header",
@@ -79,10 +214,20 @@
79
214
  "md": 4,
80
215
  "lg": 4,
81
216
  "xl": 4
217
+ },
218
+ "readInterval": {
219
+ "newLine": true,
220
+ "type": "number",
221
+ "label": "readIntervalsbfspot",
222
+ "min": 5,
223
+ "max": 300,
224
+ "default": 5,
225
+ "xs": 12,
226
+ "sm": 12,
227
+ "md": 4,
228
+ "lg": 4,
229
+ "xl": 4
82
230
  }
83
-
84
-
85
-
86
231
  }
87
232
  },
88
233
  "tab-mysql": {
@@ -135,6 +280,7 @@
135
280
  "newLine": true,
136
281
  "type": "password",
137
282
  "label": "sbfspot_DB_password",
283
+ "visible": true,
138
284
  "help": "",
139
285
  "xs": 12,
140
286
  "sm": 12,
@@ -167,7 +313,6 @@
167
313
  "size": 2
168
314
  },
169
315
 
170
-
171
316
  "sqlite_path": {
172
317
  "type": "text",
173
318
  "label": "path_to_DB_file",
package/io-package.json CHANGED
@@ -1,8 +1,34 @@
1
1
  {
2
2
  "common": {
3
3
  "name": "sbfspot",
4
- "version": "4.4.2",
4
+ "version": "5.0.1",
5
5
  "news": {
6
+ "5.0.1": {
7
+ "en": "new testing",
8
+ "de": "neue tests",
9
+ "ru": "новые испытания",
10
+ "pt": "novos testes",
11
+ "nl": "nieuwe tests",
12
+ "fr": "nouveaux essais",
13
+ "it": "nuovi test",
14
+ "es": "nuevas pruebas",
15
+ "pl": "nowe badania",
16
+ "uk": "новий тест",
17
+ "zh-cn": "新测试"
18
+ },
19
+ "5.0.0": {
20
+ "en": "ATTENTION breaking change: adapter type changed from scheduled to daemon\nupdate hints added to admin\nsuggestions from adapter checker",
21
+ "de": "ATTENTION Brechwechsel: Adaptertyp geändert von geplant nach Daemon\nupdate-hinweise zu admin hinzugefügt\nvorschläge von adapter checker",
22
+ "ru": "Изменение типа адаптера: переход с запланированного на демон\nобновление подсказок, добавленных в admin\nпредложения от adapter checker",
23
+ "pt": "Alteração de ruptura ATTENÇÃO: tipo de adaptador alterado de programado para daemon\natualizar dicas adicionadas ao administrador\nsugestões do verificador do adaptador",
24
+ "nl": "ATTENTIE break change: adapter type veranderd van gepland naar daemon\nhints aan admin bijwerken\nsuggesties van adaptercontrole",
25
+ "fr": "Changement de rupture ATTENTION : le type d'adaptateur est passé de programmé à démon\nmise à jour des conseils ajoutés à admin\nsuggestions de l'adaptateur checker",
26
+ "it": "ATTENZIONE cambio di rottura: tipo adattatore cambiato da programmato a demone\naggiornamento suggerimenti aggiunti a admin\nsuggerimenti da adattatore checker",
27
+ "es": "Cambio de ruptura de ATTENTION: tipo de adaptador cambiado de programado a daemon\nsugerencias de actualización añadidos a admin\nsugerencias del adaptador",
28
+ "pl": "UWAGA zmiana łamania: typ adaptera zmieniony z zaplanowanego na demona\naktualizacji wskazówki dodane do admin\nsugestie z sprawdzania adaptera",
29
+ "uk": "Зміна зміни тенції: тип адаптера змінено з запланованого на дамон\nоновлення натяків додано в адмін\nпропозиції від адаптера",
30
+ "zh-cn": "注意断开更改:适配器类型从预定更改为守护进程\n添加到管理员的更新提示\n来自适配器检查器的建议"
31
+ },
6
32
  "4.4.2": {
7
33
  "en": "changes requested by adapter checker\ndependencies updated",
8
34
  "de": "änderungen, die von adapter checker angefordert werden\naktualisierte abhängigkeiten",
@@ -67,32 +93,6 @@
67
93
  "pl": "aktualizacji zależności\npoprawki błędów oparte na rekomendacji sprawdzania adaptera",
68
94
  "uk": "оновлення залежності\nвиправлення помилок на основі рекомендації адаптера",
69
95
  "zh-cn": "更新依赖关系\n根据适配器检查器建议修正错误"
70
- },
71
- "4.3.3": {
72
- "en": "(René) change of dependencies\n(René) mySql dependency update",
73
- "de": "(René) Veränderung der Abhängigkeiten\n(René) mySql Abhängigkeitsupdate",
74
- "ru": "(René) изменение зависимостей\n(René) обновление зависимости mySql",
75
- "pt": "(René) mudança de dependências\n(René) atualização de dependência mySql",
76
- "nl": "(René) verandering van afhankelijkheden\n(René) mySql afhankelijkheidsupdate",
77
- "fr": "(René) changement de dépendances\n(René) Mise à jour de la dépendance mySql",
78
- "it": "(René) cambiamento delle dipendenze\n(René) aggiornamento di dipendenza mySql",
79
- "es": "(René) cambio de dependencia\n(René) mySql dependency update",
80
- "pl": "(René) zmiana zależności\nAktualizacja zależności mySql",
81
- "uk": "(Рене) зміна залежностей\n(René) mySql оновлення залежності",
82
- "zh-cn": "(René) 属地变化\n(René) MySql 依赖性更新"
83
- },
84
- "4.3.2": {
85
- "en": "(René) change of dependencies",
86
- "de": "(René) Veränderung der Abhängigkeiten",
87
- "ru": "(René) изменение зависимостей",
88
- "pt": "(René) mudança de dependências",
89
- "nl": "(René) verandering van afhankelijkheden",
90
- "fr": "(René) changement de dépendances",
91
- "it": "(René) cambiamento delle dipendenze",
92
- "es": "(René) cambio de dependencia",
93
- "pl": "(René) zmiana zależności",
94
- "uk": "(Рене) зміна залежностей",
95
- "zh-cn": "(René) 属地变化"
96
96
  }
97
97
  },
98
98
  "titleLang": {
@@ -122,7 +122,7 @@
122
122
  "uk": "Адаптер інвертора SMA (sbfspot) із віджетом vis"
123
123
  },
124
124
  "platform": "Javascript/Node.js",
125
- "mode": "schedule",
125
+ "mode": "daemon",
126
126
  "schedule": "*/15 * * * *",
127
127
  "icon": "sbfspot.png",
128
128
  "enabled": true,
@@ -207,6 +207,26 @@
207
207
  "agree",
208
208
  "cancel"
209
209
  ]
210
+ },
211
+ {
212
+ "condition": {
213
+ "operand": "and",
214
+ "rules": [
215
+ "oldVersion<=4.4.2",
216
+ "newVersion>4.4.2"
217
+ ]
218
+ },
219
+ "title": {
220
+ "en": "type of adapter changed"
221
+ },
222
+ "text": {
223
+ "en": "type of adapter changed to deamon. It might be necessary to create a new instance of adapter."
224
+ },
225
+ "level": "warn",
226
+ "buttons": [
227
+ "agree",
228
+ "cancel"
229
+ ]
210
230
  }
211
231
  ]
212
232
  },
@@ -0,0 +1,127 @@
1
+ #!/bin/sh
2
+
3
+
4
+ #todo
5
+
6
+ # Config Daten von au�en �bergebbar
7
+
8
+
9
+ cd ~
10
+ mkdir projects
11
+ cd projects
12
+
13
+ sudo apt update
14
+
15
+ sudo apt -y install make g++
16
+ sudo apt -y --no-install-recommends install bluetooth libbluetooth-dev
17
+ sudo apt -y install libboost-date-time-dev libboost-system-dev libboost-filesystem-dev libboost-regex-dev
18
+ sudo apt -y install libboost-all-dev
19
+
20
+ sudo apt -y install sqlite3 libsqlite3-dev
21
+
22
+ sudo mkdir /var/sbfspot.3
23
+ sudo mkdir /var/sbfspot.3/smadata
24
+ sudo mkdir /var/sbfspot.3/logs
25
+ sudo chown -R $USER:$USER /var/sbfspot.3/
26
+ sudo chmod -R 777 /var/sbfspot.3/
27
+
28
+
29
+ sudo apt -y install git
30
+ git clone https://github.com/SBFspot/SBFspot.git
31
+
32
+ cd SBFspot
33
+ git checkout tags/V3.9.12
34
+
35
+ cd ~/projects/SBFspot/SBFspot
36
+ make sqlite
37
+
38
+ sudo make install_sqlite
39
+
40
+
41
+ cd /usr/local/bin/sbfspot.3
42
+ sudo cp SBFspot.default.cfg SBFspot.cfg
43
+
44
+ sudo sed -i 's/BTAddress=00:00:00:00:00:00/BTAddress=01:01:01:01:01:01/' SBFspot.cfg
45
+
46
+ sudo sed -i 's/OutputPath=\/home\/pi\/smadata\/%Y/OutputPath=\/var\/sbfspot.3\/smadata\/%Y/' SBFspot.cfg
47
+ sudo sed -i 's/OutputPathEvents=\/home\/pi\/smadata\/%Y\/Events/OutputPathEvents=\/var\/sbfspot.3\/smadata\/%Y\/Events/' SBFspot.cfg
48
+ sudo sed -i 's/SQL_Database=\/home\/pi\/smadata\/SBFspot.db/SQL_Database=\/var\/sbfspot.3\/smadata\/SBFspot.db/' SBFspot.cfg
49
+
50
+
51
+ cd /usr/local/bin/sbfspot.3
52
+
53
+ sudo touch daydata
54
+ sudo chmod 775 daydata
55
+ sudo chown $USER:$USER daydata
56
+
57
+ cat >> daydata << EOF
58
+ #!/bin/bash
59
+ #
60
+ log=/var/sbfspot.3/logs/MyPlant_$(date '+%Y%m%d').log
61
+ /usr/local/bin/sbfspot.3/SBFspot -v -ad1 -am0 -ae0 >>$log
62
+ EOF
63
+
64
+ sudo chmod +x daydata
65
+
66
+ sudo touch monthdata
67
+ sudo chmod 775 monthdata
68
+ sudo chown $USER:$USER monthdata
69
+
70
+ cat >> monthdata << EOF
71
+ #!/bin/bash
72
+ #
73
+ log=/var/sbfspot.3/logs/MyPlant_$(date '+%Y%m').log
74
+ /usr/local/bin/sbfspot.3/SBFspot -v -sp0 -ad0 -am1 -ae1 -finq >>$log
75
+ EOF
76
+
77
+ sudo chmod +x monthdata
78
+
79
+ (crontab -l 2>/dev/null; echo "*/5 6-22 * * * /usr/local/bin/sbfspot.3/daydata") | crontab -
80
+ (crontab -l 2>/dev/null; echo "55 05 * * * /usr/local/bin/sbfspot.3/monthdata") | crontab -
81
+
82
+ cd /var/sbfspot.3/smadata
83
+ sqlite3 SBFspot.db < ~/projects/SBFspot/SBFspot/CreateSQLiteDB.sql
84
+
85
+ sudo apt -y install libcurl4-openssl-dev
86
+
87
+ cd ~/projects/SBFspot/SBFspotUploadDaemon
88
+ make sqlite
89
+
90
+ sudo make install_sqlite
91
+
92
+ cd /usr/local/bin/sbfspot.3
93
+ sudo cp SBFspotUpload.default.cfg SBFspotUpload.cfg
94
+
95
+ sudo sed -i 's/PVoutput_SID=/PVoutput_SID=123456789/' SBFspotUpload.cfg
96
+ sudo sed -i 's/PVoutput_Key=/PVoutput_Key=123456789/' SBFspotUpload.cfg
97
+
98
+ sudo sed -i 's/SQL_Database=\/home\/pi\/smadata\/SBFspot.db/SQL_Database=\/var\/sbfspot.3\/smadata\/SBFspot.db/' SBFspotUpload.cfg
99
+
100
+ sudo sed -i 's/LogDir=\/var\log\/sbfspot.3\//LogDir=\/var\/sbfspot.3\/logs\/' SBFspotUpload.cfg
101
+
102
+
103
+ cd /usr/local/bin/sbfspot.3/
104
+
105
+ sudo touch SBFspotUpload.service
106
+ sudo chmod 775 SBFspotUpload.service
107
+ sudo chown $USER:$USER SBFspotUpload.service
108
+
109
+ cat >> SBFspotUpload.service << EOF
110
+ [Unit]
111
+ Description=SBFspot Upload Daemon
112
+ After=mysql.service mariadb.service network.target
113
+
114
+ [Service]
115
+ User=datalogger
116
+ Type=simple
117
+ TimeoutStopSec=10
118
+ ExecStart=/usr/local/bin/sbfspot.3/SBFspotUploadDaemon
119
+ Restart=on-success
120
+ RestartSec=10
121
+
122
+ [Install]
123
+ WantedBy=multi-user.target
124
+ EOF
125
+
126
+ sudo systemctl enable /usr/local/bin/sbfspot.3/SBFspotUpload.service
127
+ sudo systemctl start SBFspotUpload
@@ -0,0 +1,27 @@
1
+ #!/bin/sh
2
+
3
+ sudo service ebusd stop
4
+
5
+ cd ~
6
+ cd projects
7
+ cd ebusd
8
+
9
+ git fetch
10
+
11
+ git pull
12
+ git checkout tags/25.1
13
+
14
+ cmake .
15
+
16
+ make
17
+
18
+ ./src/ebusd/ebusd --help
19
+
20
+ ./src/ebusd/ebusd --version
21
+
22
+ make install
23
+
24
+ sudo service ebusd start
25
+
26
+
27
+ edit /etc/default/ebusd
package/lib/tools.js CHANGED
@@ -1,7 +1,7 @@
1
1
  const axios = require('axios').default;
2
2
 
3
+ //Tests whether the given variable is a real object and not an Array
3
4
  /**
4
- * Tests whether the given variable is a real object and not an Array
5
5
  * @param {any} it The variable to test
6
6
  * @returns {it is Record<string, any>}
7
7
  */
@@ -13,18 +13,20 @@ function isObject(it) {
13
13
  return Object.prototype.toString.call(it) === '[object Object]';
14
14
  }
15
15
 
16
+ //Tests whether the given variable is really an Array
16
17
  /**
17
- * Tests whether the given variable is really an Array
18
18
  * @param {any} it The variable to test
19
19
  * @returns {it is any[]}
20
20
  */
21
21
  function isArray(it) {
22
- if (typeof Array.isArray === 'function') return Array.isArray(it);
22
+ if (typeof Array.isArray === 'function') {
23
+ return Array.isArray(it);
24
+ }
23
25
  return Object.prototype.toString.call(it) === '[object Array]';
24
26
  }
25
27
 
28
+ //Translates text to the target language. Automatically chooses the right translation API.
26
29
  /**
27
- * Translates text to the target language. Automatically chooses the right translation API.
28
30
  * @param {string} text The text to translate
29
31
  * @param {string} targetLang The target languate
30
32
  * @param {string} [yandexApiKey] The yandex API key. You can create one for free at https://translate.yandex.com/developers
@@ -43,8 +45,8 @@ async function translateText(text, targetLang, yandexApiKey) {
43
45
  }
44
46
  }
45
47
 
48
+ //Translates text with Yandex API
46
49
  /**
47
- * Translates text with Yandex API
48
50
  * @param {string} text The text to translate
49
51
  * @param {string} targetLang The target languate
50
52
  * @param {string} apiKey The yandex API key. You can create one for free at https://translate.yandex.com/developers
@@ -66,8 +68,8 @@ async function translateYandex(text, targetLang, apiKey) {
66
68
  }
67
69
  }
68
70
 
71
+ //Translates text with Google API
69
72
  /**
70
- * Translates text with Google API
71
73
  * @param {string} text The text to translate
72
74
  * @param {string} targetLang The target languate
73
75
  * @returns {Promise<string>}
package/main.js CHANGED
@@ -1,10 +1,11 @@
1
- /*
1
+ /* eslint-disable prefer-template */
2
+ /*
2
3
  * sbfspot adapter für iobroker
3
4
  *
4
5
  * Created: 15.09.2016 21:31:28
5
6
  * Author: Rene
6
7
 
7
- Copyright(C)[2016-2020][René Glaß]
8
+ Copyright(C)[2016-2025][René Glaß]
8
9
 
9
10
 
10
11
 
@@ -17,9 +18,16 @@ Copyright(C)[2016-2020][René Glaß]
17
18
  const utils = require("@iobroker/adapter-core");
18
19
  //const { json } = require("stream/consumers");
19
20
  const SunCalc = require("suncalc2");
21
+ const axios = require("axios");
22
+ const { promisify } = require('util');
23
+ const exec = promisify(require('child_process').exec)
24
+ const os = require('os');
20
25
 
21
26
  //const bluetooth_test = require("./lib/SMA_Bluetooth").test;
22
27
 
28
+ const supportedVersion = "3.9.12"
29
+
30
+ let updateTimerID = null;
23
31
 
24
32
  let adapter;
25
33
  function startAdapter(options) {
@@ -33,7 +41,61 @@ function startAdapter(options) {
33
41
  } catch (e) {
34
42
  adapter.log.error("exception catch after ready [" + e + "]");
35
43
  }
44
+ },
45
+
46
+ //#######################################
47
+ // is called when adapter shuts down
48
+ unload: function (callback) {
49
+ try {
50
+
51
+ if (intervalID != null) {
52
+ clearInterval(intervalID);
53
+ }
54
+ if (updateTimerID != null) {
55
+ clearTimeout(updateTimerID);
56
+ }
57
+ adapter && adapter.log && adapter.log.info && adapter.log.info("cleaned everything up...");
58
+ //to do stop intervall
59
+ callback();
60
+ } catch (e) {
61
+ adapter.log.error("exception catch after unload [" + e + "]");
62
+ callback();
63
+ }
64
+ },
65
+
66
+ //stateChange: async (id, state) => {
67
+ //await HandleStateChange(id, state);
68
+ //},
69
+
70
+ //#######################################
71
+ //
72
+ message: async (obj) => {
73
+ if (obj) {
74
+ switch (obj.command) {
75
+ case "Install":
76
+ adapter.log.debug("message install called");
77
+ break;
78
+ case "Update":
79
+ adapter.log.debug("message update called");
80
+ break;
81
+ case "checkInstallableversion":
82
+ await CheckVersion("installable", obj);
83
+ break;
84
+ case "checkCurrentVersion":
85
+ await CheckVersion("current", obj);
86
+ break;
87
+ case "checkSupportedVersion":
88
+ await CheckVersion("supported", obj);
89
+ break;
90
+ default:
91
+ adapter.log.error("unknown message " + obj.command);
92
+ break;
93
+ }
94
+ }
36
95
  }
96
+ //#######################################
97
+
98
+
37
99
  });
38
100
  adapter = new utils.Adapter(options);
39
101
  return adapter;
@@ -52,26 +114,46 @@ let sqlite_db;
52
114
  //---------- mySQL
53
115
  let mysql_connection;
54
116
 
55
- let killTimer;
117
+ //let killTimer;
118
+ let intervalID = null;
119
+
56
120
 
57
121
  async function main() {
58
122
 
123
+ let readInterval = 5;
124
+ if (parseInt(adapter.config.readInterval) > 0) {
125
+ readInterval = adapter.config.readInterval;
126
+ }
127
+ adapter.log.debug("read every " + readInterval + " minutes");
128
+ intervalID = setInterval(Do, readInterval * 60 * 1000);
129
+
130
+
131
+ //read at adapterstart
132
+ await Do();
133
+ }
134
+
135
+
136
+ async function Do() {
137
+
59
138
 
60
139
  //bluetooth_test();
61
140
 
62
141
 
142
+ //todo check access righst for sqlite file and folder...
143
+
144
+
63
145
  if (adapter.config.databasetype === undefined) {
64
146
  adapter.log.error("databasetype not defined. check and update settings and save");
65
- adapter.terminate ? adapter.terminate(11) : process.exit(11);
147
+ // adapter.terminate ? adapter.terminate(11) : process.exit(11);
66
148
  }
67
149
 
68
150
  //await CheckInverterVariables();
69
151
 
70
- killTimer = setTimeout(function () {
71
- //adapter.stop();
72
- adapter.log.error("force terminate ");
73
- adapter.terminate ? adapter.terminate(11) : process.exit(11);
74
- }, 2*60*1000);
152
+ //killTimer = setTimeout(function () {
153
+ // //adapter.stop();
154
+ // adapter.log.error("force terminate ");
155
+ // adapter.terminate ? adapter.terminate(11) : process.exit(11);
156
+ //}, 2*60*1000);
75
157
 
76
158
 
77
159
  let daylight = false;
@@ -94,8 +176,7 @@ async function main() {
94
176
  && (now.getHours() < times.sunset.getHours() || (now.getHours() == times.sunset.getHours() && now.getMinutes() < times.sunset.getMinutes()))) {
95
177
  daylight = true;
96
178
  }
97
- }
98
- else {
179
+ } else {
99
180
  //always
100
181
  daylight = true;
101
182
  }
@@ -170,19 +251,18 @@ async function main() {
170
251
  }
171
252
  }
172
253
  DB_Disconnect();
173
- }
174
- else {
254
+ } else {
175
255
  adapter.log.info("nothing to do, because no daylight ... ");
176
256
 
177
257
  }
178
258
 
179
259
 
180
- if (killTimer) {
181
- clearTimeout(killTimer);
182
- adapter.log.debug("timer killed");
183
- }
260
+ //if (killTimer) {
261
+ // clearTimeout(killTimer);
262
+ // adapter.log.debug("timer killed");
263
+ //}
184
264
 
185
- adapter.terminate ? adapter.terminate(11) : process.exit(11);
265
+ //adapter.terminate ? adapter.terminate(11) : process.exit(11);
186
266
 
187
267
 
188
268
  }
@@ -196,14 +276,12 @@ async function GetSystemDateformat() {
196
276
  longitude = ret.common.longitude;
197
277
  latitude = ret.common.latitude;
198
278
  adapter.log.debug("system: longitude " + longitude + " latitude " + latitude);
199
- }
200
- else {
279
+ } else {
201
280
  adapter.log.error("system.config not available. longitude and latitude set to Berlin");
202
281
  longitude = 52.520008;
203
282
  latitude = 13.404954;
204
283
  }
205
- }
206
- catch (e) {
284
+ } catch (e) {
207
285
  adapter.log.error("exception in GetSystemDateformat [" + e + "]");
208
286
  }
209
287
  }
@@ -290,8 +368,7 @@ async function CreateObject(key, obj) {
290
368
  }
291
369
  });
292
370
  }
293
- }
294
- else {
371
+ } else {
295
372
  await adapter.setObjectNotExistsAsync(key, obj);
296
373
  }
297
374
  }
@@ -385,8 +462,7 @@ async function DB_Connect() {
385
462
 
386
463
  }
387
464
 
388
- }
389
- catch (e) {
465
+ } catch (e) {
390
466
  adapter.log.error("exception in DB_Connect [" + e + "]");
391
467
  ret = false;
392
468
  }
@@ -401,7 +477,7 @@ async function DB_Query(query) {
401
477
 
402
478
  if (adapter.config.databasetype == "mySQL" || adapter.config.databasetype == "MariaDB") {
403
479
 
404
- const [rows, fields] = await mysql_connection.execute(query);
480
+ const [rows] = await mysql_connection.execute(query);
405
481
  retRows = rows;
406
482
 
407
483
  } else {
@@ -447,8 +523,7 @@ async function DB_CheckLastUploads(serial) {
447
523
 
448
524
  await adapter.setStateAsync(serial + ".sbfspot.LastUpload", { ack: true, val: lastUpload });
449
525
  }
450
- }
451
- catch (e) {
526
+ } catch (e) {
452
527
  adapter.log.error("exception in DB_CheckLastUploads [" + e + "]");
453
528
  }
454
529
  }
@@ -461,8 +536,7 @@ async function DB_GetInverters() {
461
536
  try {
462
537
  const query = "SELECT * from Inverters";
463
538
  retRows = await DB_Query(query);
464
- }
465
- catch (e) {
539
+ } catch (e) {
466
540
  adapter.log.error("exception in DB_GetInverters [" + e + "]");
467
541
  }
468
542
 
@@ -531,8 +605,7 @@ async function DB_GetInvertersData(serial) {
531
605
  //SELECT * from SpotData where Serial ='2000562095' ORDER BY TimeStamp DESC LIMIT 1
532
606
  const query = "SELECT * from SpotData where Serial =" + serial + " ORDER BY TimeStamp DESC LIMIT 1";
533
607
  retRows = await DB_Query(query);
534
- }
535
- catch (e) {
608
+ } catch (e) {
536
609
  adapter.log.error("exception in DB_GetInvertersData [" + e + "]");
537
610
  }
538
611
 
@@ -637,8 +710,7 @@ async function DB_CalcHistory_LastMonth(serial) {
637
710
  query = "SELECT strftime('%Y-%m-%d', datetime(TimeStamp, 'unixepoch')) as date, Max(`EToday`) as ertrag FROM `SpotData` WHERE `Serial` = '" + serial + "' AND TimeStamp>= " + datefrom.getTime() / 1000 + " AND TimeStamp<= " + dateto.getTime() / 1000 + " Group By strftime('%Y-%m-%d', datetime(TimeStamp, 'unixepoch'))";
638
711
  }
639
712
  retRows = await DB_Query(query);
640
- }
641
- catch (e) {
713
+ } catch (e) {
642
714
  adapter.log.error("exception in DB_CalcHistory_LastMonth [" + e + "]");
643
715
  }
644
716
 
@@ -687,11 +759,10 @@ async function CalcHistory_LastMonth(err, rows, serial) {
687
759
 
688
760
  */
689
761
 
690
- }
691
- else {
762
+ } else {
692
763
  oLastDays.push({
693
- "date": data["date"],
694
- "value": data["ertrag"]
764
+ date: data["date"],
765
+ value: data["ertrag"]
695
766
  });
696
767
  }
697
768
 
@@ -728,8 +799,7 @@ async function DB_CalcHistory_Prepare(serial) {
728
799
  query = "SELECT strftime('%Y-%m-%d', datetime(TimeStamp, 'unixepoch')) as date, ETotal FROM `SpotData` WHERE `Serial` = '" + serial + "' ORDER by `TimeStamp` ASC LIMIT 1";
729
800
  }
730
801
  retRows = await DB_Query(query);
731
- }
732
- catch (e) {
802
+ } catch (e) {
733
803
  adapter.log.error("exception in DB_CalcHistory_Prepare [" + e + "]");
734
804
  }
735
805
 
@@ -785,8 +855,7 @@ async function DB_CalcHistory_Today(serial) {
785
855
  query = "SELECT strftime('%H:%m', datetime(TimeStamp, 'unixepoch')) as time, Max(`EToday`) as ertrag FROM `SpotData` WHERE `Serial` = '" + serial + "' AND TimeStamp>= " + datefrom.getTime() / 1000 + " AND TimeStamp<= " + dateto.getTime() / 1000 + " Group By strftime('%H-%m', datetime(TimeStamp, 'unixepoch'))";
786
856
  }
787
857
  retRows = await DB_Query(query);
788
- }
789
- catch (e) {
858
+ } catch (e) {
790
859
  adapter.log.error("exception in DB_CalcHistory_Today [" + e + "]");
791
860
  }
792
861
 
@@ -842,11 +911,10 @@ async function CalcHistory_Today(err, rows, serial) {
842
911
 
843
912
  */
844
913
 
845
- }
846
- else {
914
+ } else {
847
915
  oLastDays.push({
848
- "time": data["time"],
849
- "value": data["ertrag"]
916
+ time: data["time"],
917
+ value: data["ertrag"]
850
918
  });
851
919
 
852
920
  }
@@ -879,8 +947,7 @@ async function DB_CalcHistory_Years(serial) {
879
947
  query = "SELECT strftime('%Y', datetime(TimeStamp, 'unixepoch')) as date, Max(`ETotal`) as ertrag, Min(`ETotal`) as startertrag FROM `SpotData` WHERE `Serial` = '" + serial + "' Group By strftime('%Y', datetime(TimeStamp, 'unixepoch'))";
880
948
  }
881
949
  retRows = await DB_Query(query);
882
- }
883
- catch (e) {
950
+ } catch (e) {
884
951
  adapter.log.error("exception in DB_CalcHistory_Years [" + e + "]");
885
952
  }
886
953
 
@@ -971,11 +1038,10 @@ async function CalcHistory_Years(err, rows, serial) {
971
1038
 
972
1039
  */
973
1040
 
974
- }
975
- else {
1041
+ } else {
976
1042
  oLastYears.push({
977
- "year": installyear + n,
978
- "value": parseInt(yearvalue)
1043
+ year: installyear + n,
1044
+ value: parseInt(yearvalue)
979
1045
  });
980
1046
  }
981
1047
  }
@@ -997,12 +1063,11 @@ async function CalcHistory_Years(err, rows, serial) {
997
1063
  oDate,
998
1064
  yearvalue
999
1065
  ]);
1000
- }
1001
- else {
1066
+ } else {
1002
1067
 
1003
1068
  oLastYears.push({
1004
- "year": data["date"],
1005
- "value": yearvalue
1069
+ year: data["date"],
1070
+ value: yearvalue
1006
1071
  });
1007
1072
  }
1008
1073
 
@@ -1047,8 +1112,7 @@ async function DB_CalcHistory_Months(serial) {
1047
1112
  query = "SELECT strftime('%Y-%m', datetime(TimeStamp, 'unixepoch')) as date, Max(`ETotal`) as ertrag FROM `SpotData` WHERE `Serial` = '" + serial + "' AND TimeStamp>= " + datefrom.getTime() / 1000 + " AND TimeStamp<= " + dateto.getTime() / 1000 + " Group By strftime('%Y-%m', datetime(TimeStamp, 'unixepoch'))";
1048
1113
  }
1049
1114
  retRows = await DB_Query(query);
1050
- }
1051
- catch (e) {
1115
+ } catch (e) {
1052
1116
  adapter.log.error("exception in DB_CalcHistory_Months [" + e + "]");
1053
1117
  }
1054
1118
 
@@ -1089,11 +1153,10 @@ async function CalcHistory_Months(err, rows, serial) {
1089
1153
 
1090
1154
  */
1091
1155
 
1092
- }
1093
- else {
1156
+ } else {
1094
1157
  oLastMonth.push({
1095
- "month": data["date"],
1096
- "value": data["ertrag"]
1158
+ month: data["date"],
1159
+ value: data["ertrag"]
1097
1160
  });
1098
1161
  }
1099
1162
  }
@@ -1139,8 +1202,7 @@ async function DB_AddDummyData() {
1139
1202
 
1140
1203
 
1141
1204
  }
1142
- }
1143
- catch (e) {
1205
+ } catch (e) {
1144
1206
  adapter.log.error("exception in DB_AddDummyData [" + e + "]");
1145
1207
  }
1146
1208
 
@@ -1166,6 +1228,81 @@ function DB_Disconnect() {
1166
1228
  }
1167
1229
 
1168
1230
 
1231
+ async function CheckVersion(version, msg) {
1232
+
1233
+ if (version == "installable") {
1234
+
1235
+ const version = await GetLatestVersionGithub();
1236
+
1237
+ adapter.sendTo(msg.from, msg.command, version, msg.callback);
1238
+ } else if (version == "current") {
1239
+
1240
+ const version = await GetInstalledVersion();
1241
+
1242
+ adapter.sendTo(msg.from, msg.command, version, msg.callback);
1243
+ } else if (version == "supported") {
1244
+ adapter.sendTo(msg.from, msg.command, supportedVersion, msg.callback);
1245
+ }
1246
+
1247
+ }
1248
+
1249
+
1250
+ async function GetLatestVersionGithub() {
1251
+
1252
+ let latestVersion = "unknown";
1253
+
1254
+ try {
1255
+ const url = "https://api.github.com/repos/SBFspot/SBFspot/releases/latest";
1256
+ adapter.log.debug("call " + url);
1257
+
1258
+ let result = await axios.get(url, { timeout: 5000 });
1259
+
1260
+ if (result != null && result.status == 200 && result.data != null) {
1261
+ adapter.log.info("installable version " + JSON.stringify(result.data.name));
1262
+
1263
+ latestVersion = result.data.name;
1264
+ } else {
1265
+ latestVersion = "unknown / no result";
1266
+ }
1267
+ } catch (e) {
1268
+ adapter.log.error("exception in GetLatestVersionGithub [" + e + "]");
1269
+ latestVersion = "unknown / error";
1270
+ }
1271
+ return latestVersion;
1272
+
1273
+
1274
+ }
1275
+
1276
+
1277
+
1278
+ async function GetInstalledVersion() {
1279
+
1280
+ let Version = "unknown";
1281
+
1282
+ try {
1283
+ if (os.type() == "Linux") {
1284
+ const cmd = " /usr/local/bin/sbfspot.3/SBFspot -version";
1285
+
1286
+ adapter.log.debug("call " + cmd);
1287
+
1288
+ let res = await exec(cmd);
1289
+
1290
+ Version = res.stdout;
1291
+
1292
+ adapter.log.info("result " + Version);
1293
+ } else {
1294
+ adapter.log.error("sbfspot version cannot be detected on " + os.type());
1295
+ Version = "unknown on " + os.type();
1296
+ }
1297
+ } catch (e) {
1298
+ adapter.log.error("exception in GetInstalledVersion [" + e + "]");
1299
+ Version = "unknown / error"
1300
+ }
1301
+ return Version;
1302
+
1303
+ }
1304
+
1305
+
1169
1306
 
1170
1307
 
1171
1308
  // If started as allInOne/compact mode => return function to create instance
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "iobroker.sbfspot",
3
- "version": "4.4.2",
3
+ "version": "5.0.1",
4
4
  "description": "sbfspot (SMA inverter) Adapter",
5
5
  "author": {
6
6
  "name": "René G.",
@@ -18,12 +18,13 @@
18
18
  "url": "https://github.com/rg-engineering/ioBroker.sbfspot"
19
19
  },
20
20
  "engines": {
21
- "node": ">= 18"
21
+ "node": ">= 20"
22
22
  },
23
23
  "dependencies": {
24
24
  "@iobroker/adapter-core": "^3.2.3",
25
- "better-sqlite3": "^11.8.1",
26
- "mysql2": "^3.11.5",
25
+ "axios": "^1.10.0",
26
+ "better-sqlite3": "^12.2.0",
27
+ "mysql2": "^3.14.1",
27
28
  "suncalc2": "^1.8.1"
28
29
  },
29
30
  "devDependencies": {
@@ -32,9 +33,10 @@
32
33
  "@alcalzone/release-script-plugin-license": "^3.7.0",
33
34
  "@alcalzone/release-script-plugin-manual-review": "^3.7.0",
34
35
  "@iobroker/adapter-dev": "^1.4.0",
35
- "@iobroker/testing": "^5.0.3",
36
+ "@iobroker/eslint-config": "^2.0.2",
37
+ "@iobroker/testing": "^5.0.4",
36
38
  "chai": "^5.2.0",
37
- "mocha": "^11.1.0"
39
+ "mocha": "^11.7.1"
38
40
  },
39
41
  "main": "main.js",
40
42
  "bugs": {